Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix exception when parsing EXIF data with LONG Orientation #684

Merged

Conversation

janhoy
Copy link
Contributor

@janhoy janhoy commented Aug 9, 2024

Fixes #548

Based on PR #549 and adds tests as well as a more lenient parsing.

The test jpg image is a real image from the /var/cache/cantaloupe/image/ folder of our Cantaloupe server. Somehow the generated thumbnail stored in the cache by Cantaloupe itself ended up with a SLONG datatype for Orientation field. But it turned out that the value itself was Integer, so a cast to (long) did not work. With this patch we accept LONG, SHORT, SLONG and SSHORT and then uses instanceof to do any casting to int.

I tried to shrink the size of the image from 36kb, but doing so with Apple Preview also rewrote the EXIF data with correct datatype :(

For some reason we see this bug popping up all the time with 5.0.6, so we currently run a patched version of 5.0.5 in production.

@janhoy
Copy link
Contributor Author

janhoy commented Aug 9, 2024

@jcoyne please consider this for next release

@jcoyne
Copy link
Contributor

jcoyne commented Aug 14, 2024

@janhoy Can you re-target this PR to develop and rebase it on develop? Hopefully that will get the tests passing.

@janhoy janhoy force-pushed the TIFF-EXIF-orientation-classcast branch from 4d50703 to c6e9d67 Compare August 22, 2024 13:23
@janhoy janhoy changed the base branch from release/5.0 to develop August 22, 2024 13:23
@janhoy
Copy link
Contributor Author

janhoy commented Aug 22, 2024

@jcoyne I added the tree commits on top of develop branch, force-pushed and re-targeted the PR to develop. You need to kick the tires for the test workflow...

@jcoyne
Copy link
Contributor

jcoyne commented Aug 23, 2024

Thank you @janhoy

// Thus to be lenient we accept either and convert to int (github issue #548)
if (value instanceof Long) {
orientation = Orientation.forEXIFOrientation(Math.toIntExact((long) value));
} else if (value instanceof Integer) {
Copy link
Contributor

Choose a reason for hiding this comment

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

hi @janhoy question about the else if. How would be the value instanceof Integer if the field is already instance of Long? Is that a Java typing issue when the Value is read from EXIF? This is just me not knowing enough probably. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was also surprised by this. Looks like some bug somewhere, that the EXIF typing is long but it gets stuffed into an integer, thus causing ClassCastException. That's the kind of stuff you see in the wild even if it is not as per spec.

So we could really skip the reading of EXIF type and just check the Java type of the value, since we need to fall back to that anyway. The only value in the four switch-case clauses is to trigger the warn log msg, but it could also have been in an else clause after instanceof checks of Long and Integer fails.

Copy link
Contributor

Choose a reason for hiding this comment

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

@janhoy it would be helpful to put those assumptions in a comment

Copy link
Contributor

Choose a reason for hiding this comment

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

@janhoy We are quite happy with this contribution. We'd like to get this merged for an upcoming release. Are you able to add these code comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added three lines of java comment already about this, what execlty do you feel is unclear and could you propose additional comment text to fix it?

// According to spec the orientation must be an unsigned short (16 bit)
// However, we have seen exif data in the wild with LONG and SLONG types
// Thus to be lenient we accept either and convert to int (github issue #548)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added these two lines:

// It could also happen that 'value' is in fact a Java Integer even if the
// exif data type is LONG or SLONG, so we need to check for that as well.

Hope this is mergeable and will be included in next release!

@janhoy janhoy requested a review from jcoyne October 3, 2024 08:29
@DiegoPino DiegoPino merged commit 904412b into cantaloupe-project:develop Oct 9, 2024
8 checks passed
@glenrobson
Copy link
Contributor

Thank you @janhoy for your work on this.

@janhoy janhoy deleted the TIFF-EXIF-orientation-classcast branch November 4, 2024 11:30
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.

Internal server error when a TIFF image uses EXIF long values for rotation
4 participants