Skip to content

Validate reserved words in ConvertFrom-Lua with -SkipValidation for lenient import #5

@MariusStorhaug

Description

Context

The Lua 5.4 reference manual §3.1 defines 22 reserved words that cannot be used as identifiers:

and, break, do, else, elseif, end, false, for, function, goto, if, in, local, nil, not, or, repeat, return, then, true, until, while

Both the serializer (ConvertTo-Lua) and the parser (ConvertFrom-Lua) need to handle reserved words correctly:

  • Serializer: Format-LuaKey already emits bracket-quote notation (["end"]) for reserved word keys — ensuring all output is spec-compliant and accepted by any Lua interpreter.
  • Parser: ConvertFrom-Lua does not validate that bare identifier keys and variable names are not reserved words. Invalid Lua like { end = 1 } is silently parsed.

A secondary issue exists in enum string serialization, where backslashes are double-escaped.

Request

What happens

  1. ConvertFrom-Lua silently accepts reserved words as bare keys:

    ConvertFrom-Lua -InputObject '{ end = 1 }'    # Parses — but invalid Lua syntax
    ConvertFrom-Lua -InputObject '{ while = "x" }' # Also parses — also invalid
  2. ConvertFrom-Lua silently accepts reserved words as assignment variable names:

    ConvertFrom-Lua -InputObject 'end = 1'   # Parses without error
    ConvertFrom-Lua -InputObject 'while = 42' # Parses without error
  3. Enum string escaping produces double backslashes due to an incorrect -replace pattern in ConvertTo-LuaTable.

What is expected

  1. Default behavior: ConvertFrom-Lua throws a terminating error when a reserved word appears as a bare identifier key or variable name. The error message identifies the word and suggests bracket notation.

  2. With -SkipValidation: ConvertFrom-Lua emits a warning for each reserved word encountered but continues parsing and returns the data. This supports lenient import of data that may not be spec-compliant.

  3. Bracket-notation keys with reserved word strings ({ ["end"] = 1 }) always work — these are valid Lua.

  4. Enum string serialization produces correctly escaped output.

Acceptance criteria

  • ConvertFrom-Lua throws on reserved words as bare table keys (e.g., { end = 1 }) by default
  • ConvertFrom-Lua throws on reserved words as assignment variable names (e.g., end = 1) by default
  • -SkipValidation switch suppresses errors → emits warnings and continues parsing
  • Each reserved word occurrence produces its own warning when -SkipValidation is used
  • Bracket-notation keys with reserved word strings continue to parse correctly
  • Format-LuaKey continues to emit bracket notation for reserved word keys (existing behavior)
  • Enum string serialization produces single-escaped backslashes

Technical decisions

-SkipValidation switch on ConvertFrom-Lua. Default behavior is strict — reserved words throw. With -SkipValidation, warnings are emitted per occurrence and parsing continues. This allows users to import out-of-spec data when needed while surfacing the issues via warnings.

Threading via script-scoped state. The -SkipValidation flag is stored as $script:luaSkipValidation alongside existing parser state ($script:luaPos, $script:luaString, etc.). This avoids changing the signature of internal functions (Read-LuaTable, Read-LuaValue) that are called recursively.

Validation in two locations:

  • Read-LuaTable — checks bare identifier keys inside table constructors ({ end = 1 })
  • ConvertFrom-LuaTable — checks variable names in assignment statements (end = 1)

Reserved word list placement: Defined locally in each function, matching the existing pattern in Format-LuaKey.

Enum escaping fix: The -replace '\\', '\\\\' pattern is corrected to -replace '\\', '\\'.

return keyword handling: return is consumed as a leading keyword before assignment detection (common in return { ... } patterns), so return = 42 does not trigger the reserved word check — it fails with a different parse error. Tests use while as the second assignment test word.


Implementation plan

ConvertFrom-Lua parameter

  • Add -SkipValidation switch parameter to ConvertFrom-Lua
  • Thread -SkipValidation to ConvertFrom-LuaTable as a parameter
  • Store as $script:luaSkipValidation in ConvertFrom-LuaTable for use by recursive parser functions

Parser validation

  • Add $reservedWords array and validation check in Read-LuaTable after bare identifier + = detection: throw or warn based on $script:luaSkipValidation
  • Add $reservedWords array and validation check in ConvertFrom-LuaTable after variable name extraction: throw or warn based on $script:luaSkipValidation

Serializer fix

  • Fix enum string escaping in ConvertTo-LuaTable: change -replace '\\', '\\\\' to -replace '\\', '\\'

Tests

  • Test: throws on reserved word as bare table key ({ end = 1 })
  • Test: throws on reserved word as bare table key ({ while = "loop" })
  • Test: allows reserved words in bracket notation ({ ["end"] = 1, ["while"] = 2 })
  • Test: throws on reserved word as assignment variable name (end = 1)
  • Test: throws on reserved word as assignment variable name (while = 42)
  • Test: -SkipValidation allows bare table key with warning
  • Test: -SkipValidation allows assignment variable name with warning

Metadata

Metadata

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions