Repository navigation
fix(lint): a double-quoted media src with an apostrophe is read whole, not reported missing - #5411
Merged
Merged
Conversation
…, not reported missing
Contributor
Edit accuracy: accurate 2061 (base branch 2061), smooth 1468 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
…ser reads the value
jrusso1020
approved these changes
Oct 10, 2026
jrusso1020
left a comment
Collaborator
There was a problem hiding this comment.
Approving at c72a9f6.
Every media src read now goes through readDecodedAttr, which is htmlparser2 with browser decoding. That is the parser already in the lint path, so the value is no longer pulled out by regex. mediaSrcTagRe only finds the tag now, and its quoted group is quote-aware. The private extractAttr in the duplicate-track rule is gone too.
What I checked
- Tests: the lint package passes 915/915 at the head. With main's
utils.ts,project.tsandhevcPreviewLint.tsswapped in, 7 of the 8 new tests fail. The script-string test passes on main, as the description says. - Mutants:
- Using
readAttr(no entity decoding) inmediaSrcOffails the'test. - Scanning raw
htmlagain in the missing-audio rule fails the script-string test.
- Using
- Probes, run through
lintProjecton main and on this head:
| Case | main | this PR |
|---|---|---|
src='assets/Say "hi".mp3', file exists |
reported missing as assets/Say |
clean |
| same, file absent | reported as assets/Say |
reported as assets/Say "hi".mp3 |
src="assets/Say "hi".mp3", file exists |
reported missing (undecoded) | clean |
src="assets/Narrator's.mp3", exists / absent |
reported both times | clean / reported with the decoded name |
<img src='assets/a "b".png'>, absent |
reported as assets/a |
reported with the full name |
src="" |
media_missing_src only |
same |
src=assets/a.mp3 (unquoted), absent |
not reported | not reported |
Non-blocking
- Unquoted
src: the missing-audio, missing-local-asset and HEVC rules still never see an unquotedsrc, becausemediaSrcTagRegroup 2 needs quotes. Main behaves the same way, so this isn't a regression. The duplicate-track rule does read unquoted values now, so the rules disagree slightly. Adding an unquoted alternative to that group, such as|[^\s"'=<>\x60]+, would close the gap, sincemediaSrcOfalready reads the value correctly.
CI is green (65 pass, 14 skipped).
— Rames
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 changes for the user
hyperframes lintno longer reports an existing file as missing when itssrcis double-quoted and contains an apostrophe, for example<audio src="assets/Narrator's voice take 1.mp3">. Before, the value was cut at the apostrophe (assets/Narrator) and the lint said the rendered video would be silent. Percent-encoding the apostrophe was the only workaround. An apostrophe written as'or'now resolves too, as it does in the renderer.Root cause
Lint read media
srcvalues with hand-written patterns of the form["']([^"']+)["']: whatever quote opened the value, it stopped at the first quote of either kind. Two places did this:mediaSrcTagRe(utils.ts), used by the missing-audio, missing-local-asset and HEVC-preview rules;extractAttrin the duplicate-audio-track rule, which also cutNarrator's take 1.mp3andNarrator's take 2.mp3to the same name and dropped the second as a duplicate.Fix
The package already has an attribute parser with browser-equivalent decoding,
readDecodedAttr. Every mediasrcread now goes through it:mediaSrcOf(match)reads thesrcof a tag thatmediaSrcTagRefound, and the three rules use it;readAttr/readDecodedAttrand its privateextractAttris gone.mediaSrcTagReonly locates the tags now. Its quoted-value group is quote-aware ("[^"]*"|'[^']*'), so a tag whosesrcstarts with a quote character (src="'90s theme.mp3") is no longer skipped and a missing file there is reported. Effects of reading values with the parser:'/', or&, is decoded as the renderer decodes it, so a file literally nameda&b.mp3referenced assrc="a&b.mp3"is now looked up asa&b.mp3, which is what the renderer requests;'<audio src="' + u + '">'as a string is not read as a tag;data-start=0 src=assets/a.mp3), so such projects can see a layered-audio warning that main missed;src=that only appears inside another attribute's text (<img alt="x src='ghost.png'">) is no longer reported as a missing file, and the duplicate-track rule no longer mistakes a leadingdata-var-srcfor the file name.Verification
assets/Narrator's voice take 1.mp3behind a double-quoted<audio src>is found; the same for an<img>; an apostrophe written as'is found; two layered filesNarrator's take 1.mp3/Narrator's take 2.mp3on one track warn as layered audio; asrc=inside another attribute's text is not reported; a missing'90s theme.mp3is reported; an audio tag built as a string in a script is not; the HEVC check findsAnn's clip.mp4.Why this PR is small
It is a lint-package fix with its tests. The other open PR in this lane is in the runtime and would have to restart its review to carry it.