Skip to content

Fix crash and loose matching in adjustver.py version parser#49

Open
jacquelinegarrahan wants to merge 1 commit into
epics-base:masterfrom
jacquelinegarrahan:fix/adjustver-version-parsing
Open

Fix crash and loose matching in adjustver.py version parser#49
jacquelinegarrahan wants to merge 1 commit into
epics-base:masterfrom
jacquelinegarrahan:fix/adjustver-version-parsing

Conversation

@jacquelinegarrahan

Copy link
Copy Markdown

Fix crash and loose matching in adjustver.py version parser

Branch: fix/adjustver-version-parsingmaster

Summary

.tools/adjustver.py parses a version string passed via -V/--version into
the EPICS_*_VERSION macros written to configure/CONFIG_*_VERSION. The parser
had two defects:

  1. Unguarded re.match result → uncaught traceback. The result of
    re.match(...) was indexed directly (M[2], M[3], …) with no None
    check. Any version string that failed to match crashed with:

    TypeError: 'NoneType' object is not subscriptable
    

    instead of a usable diagnostic.

  2. Unescaped . in the pattern. r'R?(\d+).(\d+).(\d+)(?:.(\d+))?(-.*)?'
    used bare ., which matches any character, so malformed inputs such as
    R7x0x10 were silently accepted as if valid.

Fix

.tools/adjustver.py:

  • Escape the separators and anchor the pattern:
    r'R?(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?(-.*)?$'
  • Add a None check that prints a clear message and sys.exit(1) when the
    version cannot be parsed.

Verification

# before (master): crashes
$ python3 .tools/adjustver.py -V garbage -n configure/CONFIG_BASE_VERSION
    ('MINOR_VERSION', M[2]),
TypeError: 'NoneType' object is not subscriptable

# after (this branch): clean error, exit 1
$ python3 .tools/adjustver.py -V garbage -n configure/CONFIG_BASE_VERSION
Unable to parse version 'garbage'; expected e.g. R1.2.3, 1.2.3, or 1.2.3.4-suffix

# valid input unchanged
$ python3 .tools/adjustver.py -V R7.0.10.1-DEV -n configure/CONFIG_BASE_VERSION
EPICS_VERSION = 7 ... EPICS_MODIFICATION = 10 ... (DEV snapshot handled)

Risk

Low. Behavior is unchanged for every well-formed version string; only
previously-malformed inputs change from "crash / silently mis-parse" to
"explicit error".

The --version regex used unescaped '.' (matching any character) and its
re.match() result was used without a None check. A malformed --version
value therefore raised an uncaught "TypeError: 'NoneType' object is not
subscriptable" traceback instead of a usable error, and inputs like
"R7x0x10" were wrongly accepted.

Escape the separators, anchor the end of the pattern, and print a clear
message + exit(1) when the version cannot be parsed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant