From 946a5228c544ffa121fd312596fb83a1aea11595 Mon Sep 17 00:00:00 2001 From: Eugenio Zuccarelli <11176606+jayzuccarelli@users.noreply.github.com> Date: Sat, 11 Jul 2026 13:06:00 +0000 Subject: [PATCH] Use ast.literal_eval instead of eval in hellaswag_arabic_pfn The endings field comes from a community dataset on the Hub; eval() executes arbitrary Python from it. ast.literal_eval parses the same string-encoded lists safely and raises on anything else, matching how other tasks already parse such fields. Fixes #1293 --- .../tasks/multilingual/tasks/arabic.py | 3 +- tests/unit/tasks/test_arabic_tasks.py | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/unit/tasks/test_arabic_tasks.py diff --git a/src/lighteval/tasks/multilingual/tasks/arabic.py b/src/lighteval/tasks/multilingual/tasks/arabic.py index 2d78f9887..226e8bac5 100644 --- a/src/lighteval/tasks/multilingual/tasks/arabic.py +++ b/src/lighteval/tasks/multilingual/tasks/arabic.py @@ -17,6 +17,7 @@ paper: """ +import ast import random import re from string import ascii_uppercase @@ -600,7 +601,7 @@ def copa_arabic_pfn(line, task_name: str = None): def hellaswag_arabic_pfn(line, task_name: str = None): ctx = re.sub(r"\[.*?\]", "", line["ctx"]) # Remove latin words within brackets endings = [ - re.sub(r"\[.*?\]", "", e) for e in eval(line["endings"]) + re.sub(r"\[.*?\]", "", e) for e in ast.literal_eval(line["endings"]) ] # endings is a string representation of a list answer_index = line["label"] instruction = "بناء على السياق التالي، اختر النهاية الصحيحة من الاقتراحات التالية" diff --git a/tests/unit/tasks/test_arabic_tasks.py b/tests/unit/tasks/test_arabic_tasks.py new file mode 100644 index 000000000..25ad9eefc --- /dev/null +++ b/tests/unit/tasks/test_arabic_tasks.py @@ -0,0 +1,51 @@ +# MIT License + +# Copyright (c) 2024 The HuggingFace Team + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import pytest + +from lighteval.tasks.multilingual.tasks.arabic import hellaswag_arabic_pfn + + +def test_hellaswag_arabic_pfn_parses_endings(): + line = { + "ctx": "sentence one [latin] and more", + "endings": "['ending one [x]', 'ending two']", + "label": 1, + } + + doc = hellaswag_arabic_pfn(line, "test_task") + + assert doc.choices == ["ending one ", "ending two"] + assert doc.gold_index == 1 + + +def test_hellaswag_arabic_pfn_rejects_non_literal_endings(): + # endings comes from a hub dataset; anything that is not a plain literal + # must raise instead of being evaluated + line = { + "ctx": "sentence", + "endings": "__import__('os').system('echo pwned')", + "label": 0, + } + + with pytest.raises(ValueError): + hellaswag_arabic_pfn(line, "test_task")