fix(core): read BMP height as signed int32 for top-down bitmaps#5227
fix(core): read BMP height as signed int32 for top-down bitmaps#5227wenshao merged 1 commit intoQwenLM:mainQwenLM/qwen-code:mainfrom he-yufeng:fix/bmp-top-down-heighthe-yufeng/qwen-code:fix/bmp-top-down-heightCopy head branch name to clipboard
Conversation
✅ Local verification —
|
|
@qwen-code /triage |
|
Thanks for the PR! Template looks good ✓ On direction: this fixes a real, concrete bug — top-down BMPs (negative height) produce a ~4-billion-pixel dimension that corrupts token estimation. The code already had the On approach: this is about as minimal as a fix gets — one line changed ( Moving on to code review and testing. 🔍 中文说明感谢贡献! 模板完整 ✓ 方向:修复了一个真实存在的 bug — top-down BMP(负高度)会产生约 40 亿像素的尺寸,破坏 token 估算。代码中已有 方案:改动极简 — 只改了一行( 进入代码审查和测试 🔍 — Qwen Code · qwen3.7-max |
Code ReviewMy independent proposal: change The PR's approach matches exactly. One-line production change, two focused tests, width correctly left as unsigned. Nothing missed, nothing extra. No blockers. TestingUnit tests (PR branch): 13/13 passed, including both new BMP cases. TypeScript: Regression proof — reverting only The test genuinely guards the bug — restoring 中文说明代码审查我的独立方案:把 PR 的方案完全一致。生产代码改了一行,两个聚焦的测试,宽度正确地保持无符号读取。没有遗漏,没有多余。无阻塞项。 测试单元测试(PR 分支): 13/13 通过,包括两个新增 BMP 用例。 TypeScript: 回归证明: 仅将 — Qwen Code · qwen3.7-max |
|
This is a textbook bugfix — the kind of PR you wish every contribution looked like. The bug is real and well-diagnosed: BMP height is a signed int32, the code read it unsigned, The two tests are exactly the right shape: one bottom-up (positive height, common case, should keep working), one top-down (negative height, the bug). The regression proof — reverting the one-line change causes exactly the top-down test to fail while bottom-up passes — confirms the tests genuinely guard the fix rather than just happening to pass. The existing maintainer verification comment on this PR already covers real BMP files through the built Verdict: Approve. ✅ 中文说明这是一个教科书级的 bug 修复——理想中每个 PR 都该有的样子。 Bug 真实且诊断清楚:BMP 高度是有符号 int32,代码用无符号读取, 两个测试恰好是合适的形态:一个 bottom-up(正高度,常见情况,应继续正常工作),一个 top-down(负高度,即 bug 所在)。回归证明——把这一行改回去恰好只有 top-down 测试失败而 bottom-up 继续通过——确认测试确实守护住了修复,而非凑巧通过。 该 PR 上已有的维护者验证评论已覆盖了通过构建后的 结论:批准。 ✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
What this PR does
Reads the BMP height field as a signed
int32instead ofuint32so top-down bitmaps report their real height.extractBmpDimensionsalready intends to handle the negative-height case (Math.abs(height)with a "Height can be negative for top-down BMPs" comment), but it reads the field withreadUInt32LE, so a negative height like-50becomes4294967246beforeMath.absruns — andMath.absof an already-huge positive number is still huge. Switching toreadInt32LEletsMath.absrecover the true height.Why it's needed
A BMP stores a negative height to signal top-down row order — a valid, spec-defined layout. With the unsigned read, any top-down BMP parses to a ~4-billion-pixel height, and after
calculateTokensWithScalingclamps tomaxPixelsthe token estimate is pinned to the per-image maximum regardless of the image's real size — a large, silent over-count for that whole class of BMPs. (Same failure mode as the TIFF SHORT fix in #5209, just on the BMP path.)Reviewer Test Plan
How to verify
Run the image tokenizer unit tests. Two new cases build a minimal BMP header: a bottom-up (positive height) BMP and a top-down (negative height) one. The top-down case asserts the height comes back as its absolute value (
50) rather than the pre-fix4294967246.npx vitest run packages/core/src/utils/request-tokenizer/imageTokenizer.test.tsExpected: 13 passed. The top-down case fails on
main(expected 4294967246 to be 50) and passes with the fix.Evidence (Before & After)
Non-UI change (token-accounting math), captured by the added unit test. Before: top-down BMP height
4294967246; after:50.Tested on
Environment (optional)
Unit tests only (
vitest).Risk & Scope