Skip to content

Fix: emit parse error for unterminated string in tag attribute (fixes #114)#608

Open
shivamtiwari3 wants to merge 1 commit into
markdoc:mainfrom
shivamtiwari3:fix/unterminated-string-tag-generates-error
Open

Fix: emit parse error for unterminated string in tag attribute (fixes #114)#608
shivamtiwari3 wants to merge 1 commit into
markdoc:mainfrom
shivamtiwari3:fix/unterminated-string-tag-generates-error

Conversation

@shivamtiwari3
Copy link
Copy Markdown

Summary

Fixes #114.

parseTags() in src/utils.ts now emits a parse-error (level: critical) when a tag has an unterminated string attribute, instead of silently discarding the tag as plain text.


Root Cause

findTagEnd() (utils.ts:26–51) uses a state machine with three states: normal, string, and escape. When it sees " in STATES.normal it transitions to STATES.string and stays there until a closing " is found. If the closing quote is missing (e.g. {% quote content="test /%}), the scanner never returns to STATES.normal, so it never matches the %} as a valid tag end and returns null.

In parseTags(), the end == null branch (previously lines 87–91) simply advanced pos past {% and called continue — the entire malformed construct was silently treated as plain text with no diagnostic.


Solution

When findTagEnd returns null, check whether a raw %} exists later in the content (via content.indexOf('%}', ...)):

  • %} present but unreachable (unterminated string): push an error token with message "Unterminated string in tag attribute". The parser in parser.ts:131–134 promotes this into a parse-error node with level critical on the AST, making it visible to validators and error reporters.
  • No %} at all: {% is not a Markdoc tag (e.g. code examples that happen to contain {%). Preserve the existing skip behaviour so no regression occurs for these cases.

The change is 28 lines in parseTags() and adds no new dependencies.


Testing

  • Added parseTags — malformed tags — generates an error token for an unterminated string attribute — reproduces the exact scenario from the issue ({% quote content="test /%}); previously produced zero error tokens, now produces one.
  • Added parseTags — malformed tags — leaves as text when closing delimiter is entirely absent — asserts that {% with no %} anywhere (e.g. code blocks) is still left as plain text, preventing regression.
  • Added parseTags — malformed tags — still parses valid tags after a malformed one — asserts that recovery works and the rest of the content is parsed normally.
  • All 262 existing specs continue to pass.

Run with:

npm test

Checklist

  • Fixes the root cause (not just the symptom)
  • New tests cover the exact failing scenario from the issue
  • All existing tests pass (262 specs, 0 failures)
  • No unrelated changes
  • Code style matches project conventions
  • Read CONTRIBUTING.md and followed its requirements

…arkdoc#114)

Root cause: parseTags() called findTagEnd() which returns null when a string
attribute has no closing quote (the scanner stays in STATES.string and never
sees the '%}' as a valid tag end). The null branch silently skipped past the
'{%' with no error, so the entire malformed tag was dropped as plain text.

Fix: when findTagEnd returns null but a raw '%}' does exist in the content,
emit an 'error' token instead of skipping — this surfaces as a critical
parse-error on the resulting AST node so callers can diagnose the problem.
When no '%}' is present at all the '{%' is genuinely not a Markdoc tag and
the original skip behaviour is preserved.
@shivamtiwari3
Copy link
Copy Markdown
Author

Hi — happy to make any further changes if helpful. Just checking if this is still under consideration.

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.

Tag is ignored when double quote is missing in tag attribute

1 participant