python / cpython

The Python programming language
https://www.python.org
Other
62.14k stars 29.86k forks source link

Plistlib fails on certain valid plist values #67182

Open a0587ef8-d338-4029-ad79-be08a4182aaa opened 9 years ago

a0587ef8-d338-4029-ad79-be08a4182aaa commented 9 years ago
BPO 22993
Nosy @ronaldoussoren, @abalkin, @ned-deily, @serhiy-storchaka

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = None created_at = labels = ['type-bug', 'library'] title = 'Plistlib fails on certain valid plist values' updated_at = user = 'https://bugs.python.org/ConnorWolf' ``` bugs.python.org fields: ```python activity = actor = 'serhiy.storchaka' assignee = 'none' closed = False closed_date = None closer = None components = ['Library (Lib)'] creation = creator = 'Connor.Wolf' dependencies = [] files = [] hgrepos = [] issue_num = 22993 keywords = [] message_count = 6.0 messages = ['232107', '232108', '232110', '232112', '232115', '263024'] nosy_count = 5.0 nosy_names = ['ronaldoussoren', 'belopolsky', 'ned.deily', 'serhiy.storchaka', 'Connor.Wolf'] pr_nums = [] priority = 'normal' resolution = None stage = None status = 'open' superseder = None type = 'behavior' url = 'https://bugs.python.org/issue22993' versions = ['Python 2.7', 'Python 3.4'] ```

a0587ef8-d338-4029-ad79-be08a4182aaa commented 9 years ago

I'm using plistlib to process plist files produced by an iphone app. Somehow, the application is generating plist files with a absolute date value along the lines of 0000-12-30T00:00:00Z.

This is a valid date, and the apple plist libraries can handle this without issue. However, it causes a ValueError if you load a plist containing it.

Minimal example:

python file:

import plistlib
test = plistlib.readPlist('./test.plist')

plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Test</key>
    <date>0000-12-30T00:00:00Z</date>
</dict>
</plist>

This fails on both python3 and python2, with the exact same error:

herp@mainnas:/media/Storage/Scripts/pFail$ python3 test.py
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    test = plistlib.readPlist('./test.plist')
  File "/usr/lib/python3.4/plistlib.py", line 164, in readPlist
    dict_type=_InternalDict)
  File "/usr/lib/python3.4/plistlib.py", line 995, in load
    return p.parse(fp)
  File "/usr/lib/python3.4/plistlib.py", line 325, in parse
    self.parser.ParseFile(fileobj)
  File "/usr/lib/python3.4/plistlib.py", line 337, in handle_end_element
    handler()
  File "/usr/lib/python3.4/plistlib.py", line 413, in end_date
    self.add_object(_date_from_string(self.get_data()))
  File "/usr/lib/python3.4/plistlib.py", line 291, in _date_from_string
    return datetime.datetime(*lst)
ValueError: year is out of range
herp@mainnas:/media/Storage/Scripts/pFail$ python test.py
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    test = plistlib.readPlist('./test.plist')
  File "/usr/lib/python2.7/plistlib.py", line 78, in readPlist
    rootObject = p.parse(pathOrFile)
  File "/usr/lib/python2.7/plistlib.py", line 406, in parse
    parser.ParseFile(fileobj)
  File "/usr/lib/python2.7/plistlib.py", line 418, in handleEndElement
    handler()
  File "/usr/lib/python2.7/plistlib.py", line 474, in end_date
    self.addObject(_dateFromString(self.getData()))
  File "/usr/lib/python2.7/plistlib.py", line 198, in _dateFromString
    return datetime.datetime(*lst)
ValueError: year is out of range
herp@mainnas:/media/Storage/Scripts/pFail$
a0587ef8-d338-4029-ad79-be08a4182aaa commented 9 years ago

Aaaand there is no markup processing. How do I edit my report?

ned-deily commented 9 years ago

(Currently, it is not possible to edit a particular message in an issue. You could add a replacement comment to the issue and ask that the older message be delete.)

This seems to be a problem date. As documented, plistlib converts plist dates to/from Python datetime.datetime objects. And, as is documented from datetime objects, the year field must be between 1 (MINYEAR) and 9999 (MAXYEAR). So, it would appear that dates with year 0 are not representable as datetime objects; it's not obvious to me how plistlib could handle a date like that without changing the API, i.e. returning something other than a datetime object or by changing the rules for datetime objects, which is very unlikely to happen.

https://docs.python.org/dev/library/plistlib.html https://docs.python.org/dev/library/datetime.html#datetime.MINYEAR

serhiy-storchaka commented 9 years ago

Another limitation is that on 32-bit platform it is impossible to load date before datetime.datetime(1901, 12, 13, 20, 45, 52) from binary plist.

>>> plistlib.loads(b'bplist003'+struct.pack('>d', -2**31 - (31 * 365 + 8) * 86400)+b'\x08\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11')
datetime.datetime(1901, 12, 13, 20, 45, 52)
>>> plistlib.loads(b'bplist003'+struct.pack('>d', -2**31 - (31 * 365 + 8) * 86400 - 1)+b'\x08\x00\x00\x00\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/serhiy/py/cpython/Lib/plistlib.py", line 1006, in loads
    fp, fmt=fmt, use_builtin_types=use_builtin_types, dict_type=dict_type)
  File "/home/serhiy/py/cpython/Lib/plistlib.py", line 997, in load
    return p.parse(fp)
  File "/home/serhiy/py/cpython/Lib/plistlib.py", line 623, in parse
    return self._read_object(self._object_offsets[top_object])
  File "/home/serhiy/py/cpython/Lib/plistlib.py", line 688, in _read_object
    return datetime.datetime.utcfromtimestamp(f + (31 * 365 + 8) * 86400)
OverflowError: timestamp out of range for platform time_t

Can second example be loaded by Apple tools on 32-bit?

serhiy-storchaka commented 9 years ago

Related issue is bpo-10733. Not all plists produced by Apple's tools can be proceeded by plistlib.

serhiy-storchaka commented 8 years ago

An issue with out of range timestamps was resolved in bpo-26709.