Add bounds check to source map VLQ decoder shift#8331
Add bounds check to source map VLQ decoder shift#8331kripken merged 2 commits intoWebAssembly:mainfrom
Conversation
readBase64VLQ() increments the shift value by 5 for each continuation digit with no upper bound. After 7 continuation digits, shift reaches 35 and 'digit << shift' on a uint32_t is undefined behavior (shifting by an amount >= the type width). Add a bounds check after incrementing shift, throwing a MapParseException for malformed VLQ values.
|
This looks valid, but we only have limited testing of source maps in this repo. My worry is if this invalid pattern is common in the wild, and it was silently ignored, while this PR would make things break. A good way to check would be to run the emscripten test suite with binaryen built with this PR, at least all tests with "debug", "source", or "dwarf" in the name. Another option might be to generate a source map that errors on this PR, then see what happens without this PR - if it was erroring anyhow, I would be less worried. |
Add a test case in BadSourceMaps verifying that a VLQ with 7 continuation digits is rejected with "VLQ value too large". This exercises the bounds check that prevents undefined behavior from shifting a uint32_t by >= 32.
|
Good point. I've added a test case (in Why this shouldn't break valid source maps: Base64 VLQ uses 5 data bits per character. A 7-continuation-digit VLQ encodes values >= 2^30 (~1 billion). Source map VLQ values represent line/column offsets and source/name indices — these are small numbers in practice (lines rarely exceed millions, columns rarely exceed thousands). Legitimate source maps should never need more than 5-6 characters per VLQ value. What happens today without the fix: On x86, Re: running emscripten tests: I don't currently have an emscripten setup to test against. If you'd prefer, I could change this to a warning + truncation instead of throwing, or you could run it through CI to see if anything breaks. But given the math, I believe any source map that would hit this was already producing wrong debug info silently. |
kripken
left a comment
There was a problem hiding this comment.
Thanks, I think this is good. That test + some emcc tests I ran now suggest to me that this is safe.
Summary
readBase64VLQ()incrementsshiftby 5 for each continuation digit with no upper bound.shiftreaches 35 anddigit << shifton auint32_tis undefined behavior (shifting by >= type width).shift, throwingMapParseExceptionfor malformed VLQ values with too many continuation digits.Test plan