Commit726901ebRecorded25 Feb 2026Repositorysigil-version

Fix exception handler double-pop causing test runner segfault

Message

OPPOPHANDLER blindly decremented the handler count even when OP_RAISE had already popped the handler for the current scope. This eroded outer exception handlers over time, eventually removing the top-level guard in main. When a test then raised an exception with no handler remaining, the process crashed with signal 139.

Add a framemark check to OPPOP_HANDLER so it only pops handlers belonging to the current frame level. Also fix test-version.sgl which called parse-version with #f (violating its string? spec), and remove dead type-guard code from parse-version and parse-constraint since their specs now enforce the contract.

Changed
 src/sigil/version.sgl | 26 +++++++++++---------------
 test/test-version.sgl |  4 ++--
 2 files changed, 13 insertions(+), 17 deletions(-)
Diff
src/sigil/version.sglmodified
@@ -117,16 +117,14 @@
117
;;; ```
118
(define (parse-version str)
119
(: string? -> (maybe version?))
120
(if (not (string? str))
121
#f
122
(let* ((str (string-trim str))
123
;; Strip leading 'v' or 'V' if present
124
(str (if (and (> (string-length str) 0)
125
(or (char=? (string-ref str 0) #\v)
126
(char=? (string-ref str 0) #\V)))
127
(substring str 1 (string-length str))
128
str)))
129
(parse-version-core str))))
+120
(let* ((str (string-trim str))
+121
;; Strip leading 'v' or 'V' if present
+122
(str (if (and (> (string-length str) 0)
+123
(or (char=? (string-ref str 0) #\v)
+124
(char=? (string-ref str 0) #\V)))
+125
(substring str 1 (string-length str))
+126
str)))
+127
(parse-version-core str)))
128
129
;;; Alias for parse-version.
130
(define string->version parse-version)
@@ -318,10 +316,8 @@
316
;;; ```
317
(define (parse-constraint str)
318
(: string? -> (maybe list?))
321
(if (not (string? str))
322
#f
323
(let ((str (string-trim str)))
324
(cond
+319
(let ((str (string-trim str)))
+320
(cond
321
((string=? str "*")
322
(list 'any))
323
((string-prefix? "^" str)
@@ -347,7 +343,7 @@
343
(and v (list '= v))))
344
(else
345
(let ((v (parse-version str)))
350
(and v (list '= v))))))))
+346
(and v (list '= v)))))))
347
348
;;; Check if a version satisfies a constraint string.
349
;;;
test/test-version.sglmodified
@@ -66,8 +66,8 @@
66
(test "invalid: letters"
67
(assert-false (parse-version "abc")))
68
69
(test "invalid: non-string"
70
(assert-false (parse-version #f))))
+69
(test "invalid: non-string raises error"
+70
(assert-error (parse-version #f))))
71
72
;; ============================================================
73
;; version->string roundtrip