Repository navigation
v0.97.0
Fixed
-
ISO 4217 Currency Code Validation (API-CURR-VALIDATE-001):
- Previous:
parse_currency()accepted invaliddefault_currencyvalues (lowercase, wrong length, non-alphabetic) and returned them verbatim - Issue: API contract violation; ISO 4217 requires exactly 3 uppercase ASCII letters
- Fix: Added
_is_valid_iso_4217_format()helper;_resolve_currency_code()now validatesdefault_currencyparameter before accepting it - Location:
parsing/currency.py_is_valid_iso_4217_format(),_resolve_currency_code() - Impact: Invalid
default_currencyvalues now return proper error tuple instead of corrupting output
- Previous:
-
Parser Async Error Context Safety (SEC-PARSER-ASYNC-ERROR-UNSAFE-001):
- Previous:
primitives.pyusedthreading.local()for parse error context - Issue: Thread-local storage leaks context between async tasks sharing the same thread
- Fix: Replaced
threading.local()withcontextvars.ContextVar, providing automatic task-local isolation - Location:
syntax/parser/primitives.py_error_context_var - Impact: Parse error context is now isolated per async task; no cross-task contamination in asyncio/ASGI
- Previous:
-
Resolver Term Argument Depth Bypass (SEC-RESOLVER-DEPTH-BYPASS-001):
- Previous: Term argument evaluation in
_resolve_term_referencebypassedexpression_guard - Issue: Malicious FTL with deeply nested term arguments could bypass depth limits
- Fix: Wrapped term argument evaluation in
with context.expression_guard:block - Location:
runtime/resolver.py_resolve_term_reference() - Impact: Term arguments now respect expression depth limits, preventing DoS
- Previous: Term argument evaluation in
-
Serializer Argument Depth Bypass (SEC-SERIALIZER-DEPTH-BYPASS-001):
- Previous:
_serialize_call_argumentsdid not wrap argument serialization indepth_guard - Issue: Malicious ASTs with deeply nested function arguments could bypass depth limits
- Fix: Added
with depth_guard:around positional and named argument serialization - Location:
syntax/serializer.py_serialize_call_arguments() - Impact: Function call arguments now respect serialization depth limits
- Previous:
-
CallArguments Blank Handling (SPEC-PARSER-BLANK-HANDLING-001):
- Previous:
parse_call_argumentsusedskip_blank_inline(spaces only) - Issue: FTL spec defines
CallArguments ::= blank? "(" ...whereblankincludes newlines - Fix: Changed to
skip_blankto allow multiline function argument formatting - Location:
syntax/parser/rules.pyparse_call_arguments() - Impact: Multiline function arguments now parse correctly per FTL specification
- Previous:
-
FunctionRegistry VAR_POSITIONAL Support (MAINT-FUNC-REGISTRY-VAR-POSITIONAL-001):
- Previous:
inject_localevalidation rejected functions with*argsand fewer than 2 named positional params - Issue: Functions using
*argscan accept(value, locale_code)positionally - Fix: Added
VAR_POSITIONALdetection; skip minimum parameter check when*argspresent - Location:
runtime/function_bridge.pyFunctionRegistry.register() - Impact: Functions with
*argssignatures now work withinject_locale=True
- Previous:
-
Currency Cache Size Constant Mismatch (MAINT-CONST-MISMATCH-001):
- Previous:
_get_currency_implusedMAX_TERRITORY_CACHE_SIZEfor its LRU cache - Issue: Currency and territory lookups have different cardinalities; shared limit is incorrect
- Fix: Added
MAX_CURRENCY_CACHE_SIZEconstant (300); updated_get_currency_implto use it - Location:
constants.py,introspection/iso.py_get_currency_impl() - Impact: Currency cache sized independently from territory cache
- Previous:
Added
-
AST Span Fields (ARCH-AST-SPAN-MISSING-001):
- Added optional
span: Span | None = Nonefield toPattern,TextElement, andPlaceableAST nodes - These nodes were the only pattern-level AST nodes missing span support
- Impact: Uniform span interface across all AST nodes for source mapping and diagnostics
- Added optional
-
MAX_CURRENCY_CACHE_SIZEconstant inftllexengine.constants(value: 300)