Repository navigation
Merge upstream mity/md4c master into the fork - #7
Open
hryhoriiK97 wants to merge 40 commits into
Open
hryhoriiK97 wants to merge 40 commits into
hryhoriiK97 wants to merge 40 commits into
Conversation
md_is_link_destination_B() ends an unbracketed destination on ISWHITESPACE(off) || ISCNTRL(off), six comparisons for every byte of the destination. The union of the two sets is exactly 0..32 plus 127, because space is the only whitespace character above 31, so (unsigned) CH(off) <= 32 || CH(off) == 127 gives the same answer in two. md_is_autolink_uri() uses the same test on the path of a <scheme:...> autolink and gets the same change. The two expressions agree for every value of signed and unsigned char and of a 16-bit WCHAR. md2html -s on a 5 MB link-heavy document goes from 53.7 ms to 52.7 ms (-2.0%, median of 15 interleaved rounds, aarch64, gcc -O2); md_parse() executes 5.0% fewer instructions on it under callgrind (x86-64). spec.txt does not move.
The suite never fed a DEL byte to md_is_link_destination_B() or md_is_autolink_uri(), nor a '<' inside an autolink URI, so those branches of the stop-character tests went unexercised. Add regression examples for each.
replace the manual tests for it created in the commit 45ec7ac.
c933a91 folded md_analyze_spoiler() into md_analyze_generic() and dropped its test that a pipe run is exactly two characters long. Since mity#419, md_collect_marks() also collects a single '|' as a potential opener and closer when MD_FLAG_WIKILINKS is set, so with MD_FLAG_SPOILERS enabled as well, unresolved single pipes left over after wiki-link resolution are paired as spoiler delimiters. "a | b | c" renders as "<p>a b c</p>" and "x | y ||" emits a "</x-spoiler>" with no opener. Restore the length test in md_analyze_marks() before handing a '|' mark to md_analyze_generic(), and add both inputs to spec-spoilers.txt.
With MD_FLAG_PERMISSIVEURLAUTOLINKS, "http://localhost:3000" and "https://example.com:8443/path" were not recognized: the first has a single-component host, the second a port, and ':' is not an allowed character after the host. A scheme URL may now have a single-component host (the scheme makes the intent explicit; WWW and e-mail autolinks still need two components), and the host may be followed by ':' and a port number. This matches what cmark-gfm does for scheme URLs. Co-Authored-By: Claude Fable 5.1 <[email protected]>
A trailing ':' or a non-numeric suffix after the host is not consumed as a port and keeps the text from becoming an autolink. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Resolve bare executable names before splitting legacy command strings. Run real-process invocation regressions from the existing test runner. Assisted-by: OpenAI GPT-6 (Codex) <[email protected]> Assisted-by: OpenAI GPT-6 Luna <[email protected]>
Assisted-by: OpenAI GPT-6 (Codex) <[email protected]>
The segmented path/query/fragment allowlists reject or truncate ordinary URLs containing colons, repeated semicolons, redirect URLs and percent escapes. A numeric port after a host is also rejected, and unmatched opening parentheses prevent the canonical GFM www example from linking. Scan the tail continuously with md4c's Unicode decoding and resolved-mark checks, then trim terminal punctuation and excess closing parentheses. Reuse ISUNICODEWHITESPACE_ so the ASCII-only build remains supported. Keep the existing host, preceding-boundary and e-mail rules. No dependency or public API is added. Host-colon tails remain permissive rather than validating numeric ports; document this policy and its overlap with mity#449. Extend the existing permissive-autolink specification with 12 examples covering paths, queries, fragments, parentheses, Unicode, terminal punctuation and Markdown boundaries. Nine examples fail before the fix. The full Debug/Release suites and focused sanitizer tests pass locally. Downstream report: https://bugs.documentfoundation.org/show_bug.cgi?id=169429 Downstream patch: https://gerrit.libreoffice.org/c/core/+/212109 Related proposal: mity#449 Signed-off-by: Emanuel Schorsch <[email protected]> Assisted by GPT 6.1 Sol High
Disable every mark in a consumed reference label so its delimiters cannot pair with surrounding text and emit unmatched span callbacks.
The footnote-label hash table points into the definition array. Sorting that array by reference index invalidates the pointers and can leave later references unresolved. Track emission order separately, including definitions first referenced within another footnote.
When a footnote-like label has no definition, the parser currently advances its opening mark before returning false. A following inline link can then become a wiki link and leave nested spans unbalanced. Compute the label start without changing the mark, and advance it only after lookup succeeds. The existing wiki-link regression changes output because its old expectation depended on the failed probe advancing that mark. The revised exact expectation matches the same input with footnotes disabled; an adjacent control pins both flag combinations. Add ordinary-link and superscript examples to the footnote suite.
Record each list-item opener boundary and whether the item contained a nonblank source line. Avoid mistaking the end of a paragraph for an empty item when its byte offset matches MD_BLOCK_LI, and retain content after a consumed link reference definition. Cover both nonempty cases and the genuinely empty-item rule in the regression suite.
Since the URL tail runs until whitespace (mity#454) and only excess ')' is trimmed at its end, a URL enclosed in square brackets or braces swallows the closing one: "[http://example.com/x]" links "http://example.com/x]", where 0.6.0 kept the ']' outside the link. Apply the same rule to ']' and '}' as to ')': only excess closing ones at the end of the tail are excluded, so "https://example.org/a[b]c" is still linked whole.
…L tail. An entity reference or a backslash escape inside the URL tail is a resolved mark, so the tail scan stopped there, and as it is not a closer mark the whole autolink was then rejected: "https://example.org/?a=b&c=d" and "https://example.org/a\_b" did not link at all. Treat them the same way as standard autolinks do: they are just characters of the URL. The link text keeps them verbatim, the href resolves the entity and keeps the backslash literal. This is also what cmark-gfm renders. The trailing-punctuation trim never splits such a mark. A trailing entity is excluded as a whole (cmark-gfm's ';' rule) and so is an escaped terminal punctuation character. Whatever the trim excluded is accepted as the follower of the autolink. The mity#152 suppression of an autolink that forms the whole text of a bracket link took the mark right before ']' as the autolink closer, which is no longer true when such marks live inside the URL. Follow the opener's 'next' instead. (Its second loop tested the wrong variable and never iterated.)
... when multiple blank lines follow each other.
This fixes O(N^2) parsing time for input generated by:
python3 -c 'import sys; sys.stdout.write("- " * 50000 + "x\n" + "\n" * 100000)'
(See also https://github.com/mity/md4c/security/advisories/GHSA-582f-rcwc-x4mp)
when jumping deep into nested list on a blank line. This fixes the counter-example with alternating blank lines with different number of initial spaces. (See also https://github.com/mity/md4c/security/advisories/GHSA-582f-rcwc-x4mp) Co-authored-by: Ilia Alshanetsky <[email protected]>
The harness evaluated q.put(prog.to_html(inp)) in the parent process and passed its result as the Process target, so md2html always ran inline and the TIMEOUT never fired. Handing prog.to_html to the child instead cannot work on Windows, where the spawn start method pickles the target and Prog.to_html is a lambda. Let subprocess enforce the timeout: pipe_through_prog() takes a timeout, kills md2html when it expires, and re-raises TimeoutExpired. Prog.to_html becomes a regular method. No child Python process is needed.
At 50000 levels the plain case took 4.2 seconds on the unfixed parser here, under the 5 second timeout, so a faster machine would pass it even with the quadratic scan back. Double the input; the regex still matches the innermost 50000 levels, which also keeps the alternating case under the 65535 repetition limit some Python builds impose.
Brings in the permissive autolink fixes (mity#449, mity#454, mity#462) and the other parser fixes since the fork last synced. The conflicts took upstream's side, then the prefix rename was reapplied. <video> stays block-level. Co-Authored-By: Claude Opus 5.5 <[email protected]>
`entity.h` also matched inside `enrmrkd-entity.h`, so every run wrote `enrmrkd-enrmrkd-entity.h` and broke the build. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This was referenced Nov 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What/Why?
The fork was 38 commits behind
mity/md4c. This merge brings in the permissive autolink fixes that software-mansion/enriched-markdown#961 needs (mity#449, mity#454, mity#462) and the other parser fixes since the last sync.The
ENRMRKD_rename and the<video>block-level patch are both preserved.Merge conflicts:
README.md,src/enrmrkd.c(2 hunks),src/enrmrkd-entity.candtest/spec-permissive-autolinks.txt. All took upstream's side, thenscripts/rename-upstream-symbols.plreapplied the prefix.Rename script fix:
entity.halso matched insideenrmrkd-entity.h, so every run producedenrmrkd-enrmrkd-entity.hand broke the build, including on cleanmaster. The second commit fixes that.Known script issue, not fixed: the script still rewrites the upstream names in the README's explanatory sentence (
md_parse(),MD_FLAG_TABLES,md4c.h). I restored that sentence by hand here, and it needs restoring after any full run.Testing
scripts/run-tests.py: all spec suites and all 36 pathological inputs pass, including the<video>cases inspec-addendum.txt.scripts/check-exported-symbols.shpasses.test-core-parser.shpasses and the golden AST dump, including everyVideonode, is unchanged. The #961 autolink runner also passes.Needs a follow-up in enriched-markdown:
https://e.com/😀/bareinfixtures/block_ids/document.mdnow autolinks, soids.txtgains one link id when these sources are vendored.🤖 Generated with Claude Code