jokiazhang / metadata-extractor

Automatically exported from code.google.com/p/metadata-extractor
0 stars 0 forks source link

ICC Reader Overflow #37

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Try to read metadata of the attached file

What is the expected output? What do you see instead?
Instead of the result we have exception, that crashes all the results.

What version of the product are you using? On what operating system?
2.5.0RC2. Windows XP SP3.

Please provide any additional information below.

IccReader.java
...
    // Process 'ICC tags'
    int tagCount = reader.getInt32(IccDirectory.TAG_ICC_TAG_COUNT);
    directory.setInt(IccDirectory.TAG_ICC_TAG_COUNT, tagCount);

    for (int i = 0; i < tagCount; i++) {
        int pos = 128 + 4 + i*12;
        int tagType = reader.getInt32(pos);
        int tagPtr = reader.getInt32(pos + 4);
        int tagLen = reader.getInt32(pos + 8);
        if (tagPtr + tagLen > data.length)
            throw new BufferBoundsException(data, tagPtr, tagLen);
        byte[] b = new byte[tagLen];
        System.arraycopy(data, tagPtr, b, 0, tagLen);
        directory.setByteArray(tagType, b);
    }
...
The biggest value of tagPtr and tagLen is 7FFF FFFF.
Try to imagine that tha values are not correct now and both are clothe to to 
max value. 

If we plus them to each other - we can overflow the int type and get... 
negative number. And just after that moment I can't understand the logic of 
java. In watch list if we combine them we will get the negative value. But in 
if change code to
    if ((tagPtr + tagLen > data.length) || (tagPtr + tagLen < 0))
       throw new BufferBoundsException(data, tagPtr, tagLen);
it won't work. Java behave herself very strange.

In my file the third ICC possible tag will give tagLen = 1443583418.
And this construction will crash the programm.
byte[] b = new byte[tagLen];

Original issue reported on code.google.com by superpre...@gmail.com on 30 Oct 2011 at 5:18

Attachments:

GoogleCodeExporter commented 9 years ago
Sorry -
if ((tagPtr + tagLen > data.length) || (tagPtr + tagLen < 0))
solves the problem - I forgot to update with new jar.

Original comment by superpre...@gmail.com on 30 Oct 2011 at 5:21

GoogleCodeExporter commented 9 years ago
Hi @superprepod,

Thanks for the bug report.  It seems to me that you were not using the latest 
version of the code when you hit this bug.  The newer version has more robust 
handling of these bounds checks.  In fact, they're all routed through the new 
BufferReader class, which performs the bounds check as:

    private void CheckBounds(final int index, final int bytesRequested) throws BufferBoundsException
    {
        if (bytesRequested < 0 || index < 0 || (long)index + (long)bytesRequested - 1L >= (long)_buffer.length)
            throw new BufferBoundsException(_buffer, index, bytesRequested);
    }

The 32-bit ints are cast into 64-bit ints, so they won't overflow when added.

I see the following ICC output from the file you included:

[ICC Profile] Profile Bytes = 13912 bytes binary data
[ICC Profile] Profile Size = -2119073308
[ICC Profile] CMM Type = ��I
[ICC Profile] Version = -126.7.11
[ICC Profile] Class = Unknown (�߃)
[ICC Profile] Color space = �C�u
[ICC Profile] Profile Connection Space = ����
[ICC Profile] Profile Date/Time = Mon Sep 01 15:06:28 BST 36719
[ICC Profile] Signature = �1�b
[ICC Profile] Primary Platform = Unknown (����)
[ICC Profile] Device manufacturer = �U��
[ICC Profile] Device model = -2034923802
ERROR: Reading ICC Header BufferBoundsException:Attempt to read 50740 bytes 
from beyond end of buffer (requested index: 324, max index: 31999)
ERROR: Reading ICC Header BufferBoundsException:Attempt to read 1443583418 
bytes from beyond end of buffer (requested index: 1438274791, max index: 31999)
ERROR: Reading ICC Header BufferBoundsException:Attempt to read from buffer 
using a negative index (-441509772)
[ICC Profile] XYZ values = 34868.53 34963.535 35058.535
[ICC Profile] Tag Count = -1918595631
[ICC Profile] CMM Flags = -2047572444
[ICC Profile] Rendering Intent = Unknown (-2016049147)
[ICC Profile] Device attributes = -8712627692111493211

It does indeed seem that, at some point, the reading of these values failed.  
All of these values look like complete rubbish.

Have you been process this file in other software packages to read the ICC data 
correctly?

Original comment by drewnoakes on 14 Nov 2011 at 11:29

GoogleCodeExporter commented 9 years ago
I used metadata-extractor-2.5.0-RC2-src.jar sources.
>>> All of these values look like complete rubbish.
It maybe so - looks like a crash test for your application.
>>> Have you been process this file in other software packages to read the ICC 
data correctly?
No. It's a completely random file I found on some harddrive.
Mayby it was damaged or something.

Original comment by superpre...@gmail.com on 15 Nov 2011 at 12:39

GoogleCodeExporter commented 9 years ago
Thanks for letting me know.  In that case I'll close this issue.  The latest 
code prevents against the crash you were seeing and logs the out-of-bounds 
errors appropriately.

It would be nice to know when values like these are corrupt, as the extraction 
process still reports some strange values for the directory.  I don't know of a 
reliable way to do this offhand.

If you or someone else is able to demonstrate that the file does in fact 
contain valid ICC data, then I'll reopen this issue and try to fix it.

Thanks again.

Original comment by drewnoakes on 15 Nov 2011 at 2:11