markedjs / markedjs/marked

Bug: Architectural deviations from CommonMark specification

Open
#3,996 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

L2 - annoying
Dominant language
JavaScript
Stars
37.2k
Forks
3.7k
Avg merge
4d 3h
Merged PRs (30d)
19

Description

What marked gets wrong

As a direct port of JavaScript's marked, we inherited a heavily tested and optimized architecture. However, marked.js intentionally deviates from the strict CommonMark specification in favor of its own flavor and historical design decisions.

To achieve 95.2% CommonMark compliance in marked-rs, we had to painstakingly identify and fix several structural issues in marked.js's design.

1. Escaping and Autolinks

The bug: marked.js escapes autolinks incorrectly in strict mode, especially emails. The marked.js regex parser uses decodeURIComponent and encodes HTML entities, but it fails to follow the exact character encoding rules defined in CommonMark §6.2.

The fix: We implemented a strict encode_email and encode_href utility that manually percent-encodes characters according to the CommonMark spec, avoiding the browser-centric heuristics used by marked.js.

2. Delimiter Stacks and Emphasis

The bug: marked.js parses emphasis using monolithic regular expressions. This approach cannot correctly handle deeply nested emphasis or emphasis intertwined with links (which the spec handles via a "delimiter stack").

The fix: We replaced the regex-based emphasis parsing with a true CommonMark §6.2 delimiter stack. This fixed over 100 failing tests related to overlapping bold, italic, and link delimiters.

3. List Item Fuzziness

The bug: marked.js allows list items to have arbitrary varying indentation and considers them part of the same list. CommonMark has strict rules regarding the "list item indent" (the length of the marker plus spaces).

The fix: We track line_idx and indent accurately in the Lexer, preventing list items with incompatible indentation from merging.

4. Quadratic Label Parsing

The bug: marked.js regexes for link references and inline links can exhibit catastrophic backtracking or O(N²) behavior on deeply nested brackets or very long unmatched labels.

The fix: marked-rs caps label length to 999 characters (as specified in CommonMark) and manually iterates balanced brackets without unbounded regex backtracking.

5. Task List Attributes

The bug: marked.js outputs <input disabled="" type="checkbox" checked="">. When differentially fuzzing, this seemingly innocent reordering of HTML attributes causes massive diff failures.

The fix: We strictly matched marked.js's precise attribute output order to ensure our fuzzing harness could generate a 1:1 match.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing marked.js behavior with the CommonMark sections cited for escaping and autolinks, delimiter stacks, list indentation, label parsing, and task-list attributes. The issue provides no specific marked.js file, failing test, or reproduction; done would require defining and verifying a scoped set of architectural corrections against the stated compliance and output requirements.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.