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

Uncatchable error thrown by exiv2 #8

Closed
WNiels opened this issue Jan 31, 2020 · 8 comments
Closed

Uncatchable error thrown by exiv2 #8

WNiels opened this issue Jan 31, 2020 · 8 comments
Labels

Comments

@WNiels
Copy link

WNiels commented Jan 31, 2020

Bug description:
While reading some of my images, i get the following error printed to console:

Error: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 31578, exceeds buffer size by 76 Bytes; truncating the entry

This error seems to be thrown by exiv2 but is not translated into a catchable python error.

Expected behaviour:
The error should be catchable.
A UpperBoundaryError extending Exception should be thrown.
The following code should be able to catch this error.

try:
    exif = im.read_exif() # where img is a valid pyexiv2.Image object
except BaseException as e:
    print(e)

What i found so far:
I traced the error down to the following function in core.py:

    def _open_image(self):
        """ Let C++ program open an image and read its metadata,
        save as a global variable in C++ program. """
        api.open_image.restype = ctypes.c_char_p
        ret = api.open_image(
            self.filename).decode()  # WIP: "Error: Upper boundary of data (...)" seems to originate here.
        if ret != OK:
            raise RuntimeError(ret)

Edit
Added new findings.

@LeoHsiao1
Copy link
Owner

LeoHsiao1 commented Jan 31, 2020

Hi!
I've noticed that some of the exceptions thrown by exiv2 are not caught properly by python, and the exception you mentioned is one of them, which is defined here.
I will try to deal with this problem next week.
Please send me a picture that can raise this exception so that I can debug it.

@WNiels
Copy link
Author

WNiels commented Jan 31, 2020

Thanks for the fast reply, i have sent you an email with a picture for debugging.

@LeoHsiao1
Copy link
Owner

LeoHsiao1 commented Feb 16, 2020

Hi!
I've been a bit lazy lately, so I just released the new version today.
In version 2.0.0, stderr's log 'EXV_ERROR' will be converted to an exception. For example:

>>> from pyexiv2 import Image
>>> img = Image(r'c:\Users\Leo\Desktop\CIMG7607_recompress.JPG') 
Traceback (most recent call last):   
  File "<stdin>", line 1, in <module>
  File "C:\Users\Leo\AppData\Local\Programs\Python\Python38\lib\site-packages\pyexiv2\core.py", line 19, in __init__
    self.img = api.open_image(filename.encode(encoding))
RuntimeError: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 30384, exceeds buffer size by 76 Bytes; truncating the entry

In addition, I have solved the UnicodeDecodeError you mentioned in the email, by adding a parameter encoding='utf-8' to some methods. For example:

>>> img.read_exif()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
>>> img.read_exif(encoding='ISO-8859-1')
{'Exif.Image.Make': 'CASIO COMPUTER CO.,LTD ', 'Exif.Image.Model': 'EX-Z50 ', ...}

@LeoHsiao1
Copy link
Owner

Oops! I found that in the first case, your image will not be opened.
The error log of exiv2 will not interrupt the program, but it will become fatal after it is converted into an exception.
So what about making it an optional feature?
For example:

>>> import pyexiv2
>>> img = pyexiv2.Image(r'c:\Users\Leo\Desktop\CIMG7607_recompress.JPG')
Error: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 30384, exceeds buffer size by 76 Bytes; truncating the entry
>>> pyexiv2.convert_error_log_to_exception()    # Enable
>>> img = Image(r'c:\Users\Leo\Desktop\CIMG7607_recompress.JPG')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\1\pyexiv2\pyexiv2\core.py", line 21, in __init__
    self.img = api.open_image(filename.encode(encoding))
RuntimeError: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 30384, exceeds buffer size by 76 Bytes; truncating the entry

@WNiels
Copy link
Author

WNiels commented Feb 17, 2020 via email

@LeoHsiao1
Copy link
Owner

I added a function pyexiv2.set_log_level() to the dev branch.

You can use the following code:

>>> import pyexiv2
>>> img = pyexiv2.Image(r'c:\Users\Leo\Desktop\CIMG7607_recompress.JPG')
RuntimeError: Upper boundary of data for directory Casio2, entry 0x2000 is out of bounds: Offset = 0x00000822, size = 30384, exceeds buffer size by 76 Bytes; truncating the entry
>>> pyexiv2.set_log_level(4)      # Ignore the error log
>>> img = pyexiv2.Image(r'c:\Users\Leo\Desktop\CIMG7607_recompress.JPG')

>>> data = img.read_exif()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
>>> data = img.read_exif(encoding='ISO-8859-1')      # Use an appropriate encoding
>>> img.close()

If there are no problems, I will add this feature to version 2.1.0.

@LeoHsiao1
Copy link
Owner

I have released version 2.1.0

@github-actions
Copy link

github-actions bot commented Aug 2, 2021

This issue has been automatically closed because there has been no activity for a month.

@github-actions github-actions bot locked and limited conversation to collaborators Aug 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants