Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion evalai/utils/updates.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import requests

from distutils.version import StrictVersion
from packaging.version import Version as StrictVersion

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C2 '__version__\s*<\s*latest_version|get_latest_version\(' evalai/main.py evalai/utils/updates.py

Repository: Cloud-CV/evalai-cli

Length of output: 654


🏁 Script executed:

sed -n '6,30p' evalai/utils/updates.py

Repository: Cloud-CV/evalai-cli

Length of output: 395


Return a parsed Version object instead of a string from get_latest_version()

The helper sorts releases using StrictVersion but returns a raw string from the release list. Consequently, evalai/main.py compares __version__ and latest_version as strings, causing lexicographic errors (e.g., 0.9.0 fails to trigger an update against 0.10.0).

Modify get_latest_version() to return a StrictVersion instance (strict_version = StrictVersion(versions[-1]); return strict_version) and update evalai/main.py to parse __version__ before comparison:

- if __version__ < latest_version:
+ if StrictVersion(__version__) < latest_version:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@evalai/utils/updates.py` at line 3, Update get_latest_version() in updates.py
so it returns a parsed StrictVersion object instead of the raw release string,
using the existing StrictVersion alias imported from packaging.version. Then
update the version check in evalai/main.py to parse __version__ with
StrictVersion before comparing it to latest_version, so both sides use version
objects and not lexicographic string comparison.



def get_latest_version():
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ beautifultable==0.7.0
boto3>=1.9.88
click==6.7
docker==3.6.0
lxml==4.6.2
lxml>=4.6.2,<5.0; python_version < "3.12"
lxml>=5.0.0; python_version >= "3.12"
Comment on lines +6 to +7

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -C2 --type=py '\bfrom lxml\b|\bimport lxml\b|\biterparse\s*\(|\bETCompatXMLParser\s*\(' .

Repository: Cloud-CV/evalai-cli

Length of output: 157


🌐 Web query:

What is the first patched lxml 5.x release for GHSA-vfmq-68hx-4jfw / PYSEC-2026-87, and is lxml 5.0.0 affected?

💡 Result:

The vulnerability GHSA-vfmq-68hx-4jfw (also tracked as PYSEC-2026-87 and CVE-2026-41066) was fixed in lxml 6.1.0 [1][2][3]. Consequently, there is no patched lxml 5.x release for this issue, as it remained unpatched in the 5.x series [1][4]. Lxml 5.0.0 is affected by this vulnerability because the default configuration for iterparse and ETCompatXMLParser still allowed entity resolution (resolve_entities=True) at that time [1][2]. While lxml 5.0 introduced a change to default resolve_entities='internal' for normal XML and HTML parsers, this change was not applied to iterparse or ETCompatXMLParser until version 6.1.0 [1][2].

Citations:


Bump lxml to >=6.1.0 for Python 3.12+ due to XXE (GHSA-vfmq-68hx-4jfw).

GHSA-vfmq-68hx-4jfw affects lxml 5.0.0–5.x; the first patched release is 6.1.0. Your current pin lxml>=5.0.0; python_version >= "3.12" can resolve to an affected version.

Update both markers to require 6.1.0 minimum:

required change
lxml>=4.6.2,<5.0; python_version < "3.12"
lxml>=6.1.0; python_version >= "3.12"

Even though no explicit lxml imports or iterparse/ETCompatXMLParser calls were found in Python sources, the dependency may be consumed transitively or via non-Python entrypoints. Since the advisory remains unpatched in the 5.x series, pinning to 6.1.0+ eliminates this risk.

[remove: and security flags once updated.]

🧰 Tools
🪛 OSV Scanner (2.4.0)

[HIGH] 6-6: lxml 5.0.0: undefined

(PYSEC-2026-87)


[HIGH] 6-6: lxml 5.0.0: lxml: Default configuration of iterparse() and ETCompatXMLParser() allows XXE to local files

(GHSA-vfmq-68hx-4jfw)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@requirements.txt` around lines 6 - 7, The Python 3.12+ lxml pin is still
allowed to resolve to vulnerable 5.x releases, so update the version marker in
requirements.txt to require lxml 6.1.0 or newer for python_version >= "3.12"
while leaving the Python <3.12 constraint unchanged; adjust the existing lxml
dependency entries only, using the lxml requirement lines as the reference
point.

Source: Linters/SAST tools

python-dateutil==2.7.3
requests==2.25.1
validators==0.12.6
Expand Down
14 changes: 10 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#!/usr/bin/env python
import io
import os
import sys

from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand
from distutils.util import convert_path


# We use a manual way to find the version file path for CI compatibility
def get_version_path(*paths):
return os.path.join(os.path.dirname(__file__), *paths)


class PyTest(TestCommand):
Expand All @@ -15,13 +20,12 @@ def finalize_options(self):

def run_tests(self):
import pytest

sys.exit(pytest.main(self.test_args))


PROJECT = "evalai"
package_config = {}
version_file_path = convert_path("evalai/version.py")
version_file_path = get_version_path("evalai", "version.py")

with io.open("README.md", encoding="utf-8") as f:
long_description = f.read()
Expand All @@ -34,7 +38,9 @@ def run_tests(self):

tests_require = [
"coverage",
"flake8==7.1.2",
"packaging",
"coveralls==1.3.0",
"flake8==3.0.4",
Comment on lines +41 to +43

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Does flake8 3.0.4 support Python 3.12 or Python 3.13?

💡 Result:

No, Flake8 version 3.0.4 does not support Python 3.12 or Python 3.13. Flake8 3.0.4 was released on August 8, 2016 [1][2], long before the release of Python 3.12 or 3.13. Flake8 is tightly coupled to the version of Python on which it runs because it must be able to parse the syntax of the code it checks [3]. Support for Python 3.12 was only introduced much later, starting with Flake8 version 6.1.0, released in July 2023 [4]. Consequently, version 3.0.4 lacks the necessary infrastructure and language feature support to correctly parse or lint Python 3.12 or 3.13 code.

Citations:


Remove the outdated flake8==3.0.4 pin to enable Python 3.13 support

flake8==3.0.4 (released Aug 2016) is incompatible with Python 3.12 and 3.13, as support for these versions was only introduced in flake8 6.1.0. Retaining this pin in tests_require will cause linting failures on target CI environments. Update to flake8>=6.1.0.

    "packaging",
    "coveralls==1.3.0",
    "flake8==3.0.4",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@setup.py` around lines 41 - 43, Remove the outdated flake8 pin from the
tests_require list in setup.py and update it to a Python 3.13-compatible
version, using the existing dependency entry alongside coveralls. Locate the
dependency declaration near the flake8 package name and replace flake8==3.0.4
with flake8>=6.1.0 so the test/lint environment works on newer Python versions.

"pytest==3.5.1",
"pytest-cov==2.5.1",
"pytest-env==0.6.2",
Expand Down