Skip to content

common: unescape the string form of param_string_or_array - #9598

Open
Mohil-Ahuja wants to merge 1 commit into
ElementsProject:masterfrom
Mohil-Ahuja:fix-dev-splice-newline-script
Open

Mohil-Ahuja wants to merge 1 commit into
ElementsProject:masterfrom
Mohil-Ahuja:fix-dev-splice-newline-script

Conversation

@Mohil-Ahuja

Copy link
Copy Markdown

Fixes #9553.

dev-splice scripts with segments separated by real newlines fail to compile over JSON-RPC, although doc/dev-splice.7.md says segments are "separated by newlines or semicolons" and the tokenizer in common/splice_script.c already treats '\n' as TOK_DELIMITER. The same script with ; works.

The tokenizer is fine; the script just never contains a newline. dev-splice reads script_or_json through param_string_or_array(), whose string case falls through to param_string(), which copies the raw token bytes without decoding escapes. A JSON "\n" escape therefore arrives in parse_splice_script() as a backslash followed by n. You can see it in the report: the compiler error echoes the script back with a literal backslash-n where the segment break should be. lightning-cli JSON-encodes its arguments, which is why the $'...\n...' form fails the same way.

The fix is one line: use param_escaped_string() for the string case, the same helper used for other free-text parameters such as invoice descriptions. dev-splice is the only caller of param_string_or_array(), so nothing else changes behaviour. The array case is untouched.

Tests

Added string_or_array() to common/test/run-param.c, covering a "\n" escape decoding to a newline, an escaped backslash, and the array path being passed through.

  • Against the current code it fails as expected: Assertion `streq(res->str, "wallet -> 1sat\n1sat -> x")' failed
  • With the fix it passes.

I also ran the other unit tests that compile in json_param.c (run-bolt11, run-json_filter, run-json_remove) and run-splice_script; all pass. I haven't run the Python integration suite.

One behaviour note: param_escaped_string() rejects \u escapes, so a script containing one now gets a clear "should be a string (without \u)" error instead of reaching the compiler. Scripts are plain ASCII keywords, amounts and ids, so I don't think that matters, but I'm mentioning it in case you'd rather handle it differently.

Checklist

  • The changelog has been updated in the relevant commit(s) according to the guidelines.
  • Tests have been added or modified to reflect the changes.
  • Documentation has been reviewed and updated as needed. (The docs already describe the intended behaviour; no change needed.)
  • Related issues have been listed and linked, including any that this PR closes.
  • Important All PRs must consider how to reverse any persistent changes for tools/lightning-downgrade. (No persistent state is touched.)

dev-splice documents that script segments are "separated by newlines or
semicolons", and the script tokenizer treats '\n' as a delimiter, yet a
newline-separated script sent over JSON-RPC fails to compile:

    "message":"Splice script compile failed",
    "compiler_error":["Missing sat amount. A sat amount or '*' is
    required here", ..., "Compiler phase: validate_and_clean"]

while the same script with ';' separators works.

The script never contains a newline.  dev-splice reads script_or_json
through param_string_or_array(), whose string case calls param_string(),
which copies the raw token bytes.  A JSON "\n" escape therefore reaches
parse_splice_script() as a backslash followed by 'n', which is neither a
delimiter nor whitespace, so the segments are never split.  lightning-cli
JSON-encodes its arguments, so the same happens there.

Use param_escaped_string() for the string case so escapes are decoded,
as they already are for free-text parameters such as invoice
descriptions.  dev-splice is the only caller of param_string_or_array().

Fixes: ElementsProject#9553
Changelog-Fixed: JSON-RPC: `dev-splice` accepts scripts whose segments are separated by newlines, as documented.

This branch has not been deployed

No deployments
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.

dev-splice: newline-separated script segments fail to compile via JSON-RPC

1 participant