Skip to content

Reject invalid WMF unitsPerInch=0 to prevent infinite scaling#1045

Open
jmestwa-coder wants to merge 1 commit intoapache:trunkfrom
jmestwa-coder:wmf-unitsPerInch-zero-validation
Open

Reject invalid WMF unitsPerInch=0 to prevent infinite scaling#1045
jmestwa-coder wants to merge 1 commit intoapache:trunkfrom
jmestwa-coder:wmf-unitsPerInch-zero-validation

Conversation

@jmestwa-coder
Copy link
Copy Markdown

Summary

Reject invalid WMF files where unitsPerInch = 0 to prevent unsafe scaling behavior.


Problem

unitsPerInch from the placeable WMF header is used as a divisor in scaling calculations.

If it is 0, this leads to:

  • Division by zero
  • Infinite dimensions
  • Potentially excessive image allocation

This originates from externally supplied WMF input.


Root Cause

unitsPerInch is not validated before being used in scaling.


Fix

  • Read unitsPerInch as unsigned (readUShort)
  • Reject unitsPerInch == 0 at the parser boundary by throwing RecordFormatException

Why This Change

Allowing unitsPerInch = 0 produces infinite dimensions during scaling, which can result in unsafe memory allocation.

Rejecting this value prevents undefined and unsafe behavior during WMF processing.


Tests

  • Added regression test for unitsPerInch = 0 → verifies rejection
  • Added valid case → verifies finite, positive dimensions

Tests are deterministic and in-memory.


Compatibility

  • No API changes
  • No behavior change for valid WMF files
  • Only invalid input is rejected

@pjfanning
Copy link
Copy Markdown
Member

@jmestwa-coder can you describe what happens when the new tests are run without the main source change? Maybe the tests could be documented with this detail.

unitsPerInch = leis.readShort();
unitsPerInch = leis.readUShort();
if (unitsPerInch == 0) {
throw new RecordFormatException("Invalid WMF placeable header unitsPerInch: " + unitsPerInch);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add RecordFormatException to the throws clause

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve updated the constructor signature to explicitly declare RecordFormatException for consistency with the parsing code.

@jmestwa-coder jmestwa-coder force-pushed the wmf-unitsPerInch-zero-validation branch from 93bcea9 to b892e71 Compare April 8, 2026 18:03
@jmestwa-coder
Copy link
Copy Markdown
Author

here’s what happens when the new tests are run without this change:

When unitsPerInch = 0 is parsed, it is later used as a divisor during scaling. This results in infinite dimensions.

Those values are then used when creating the BufferedImage, where they get converted to integers. In practice, this can turn into very large dimensions (close to Integer.MAX_VALUE), which may lead to excessive memory allocation attempts or runtime failures.

So without this fix:

  • The parser accepts unitsPerInch = 0
  • Scaling produces infinite dimensions
  • Rendering may attempt to allocate extremely large images

With this change:

  • The invalid value is rejected early at the parser boundary
  • The unsafe scaling and allocation path is never reached

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants