skarim / vobject

A full-featured Python package for parsing and creating iCalendar and vCard files
https://vobject.sameenkarim.com
255 stars 93 forks source link

vobject fails to parse this vcard #160

Open Volker-Weissmann opened 3 years ago

Volker-Weissmann commented 3 years ago

This code:

import vobject
el = """BEGIN:VCARD
VERSION:2.1
N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:;=57=6F=6C=6C=6B=6E=C3=A4=75=65=6C=20=53=6F=63=6B=65=6E=62=61=72=74=20=
=45=50;;;
FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=57=6F=6C=6C=6B=6E=C3=A4=75=65=6C=20=53=6F=63=6B=65=6E=62=61=72=74=20=
=45=50
TEL;CELL:+123456
TEL;CELL:+123456
END:VCARD"""
print(vobject.readOne(el))

fails with the message

Traceback (most recent call last):
  File "/path/to/script.py", line 32, in <module>
    print(vobject.readOne(el))
  File "/home/volker/.local/lib/python3.9/site-packages/vobject/base.py", line 1155, in readOne
    return next(readComponents(stream, validate, transform, ignoreUnreadable,
  File "/home/volker/.local/lib/python3.9/site-packages/vobject/base.py", line 1101, in readComponents
    vline = textLineToContentLine(line, n)
  File "/home/volker/.local/lib/python3.9/site-packages/vobject/base.py", line 925, in textLineToContentLine
    return ContentLine(*parseLine(text, n), **{'encoded': True,
  File "/home/volker/.local/lib/python3.9/site-packages/vobject/base.py", line 813, in parseLine
    raise ParseError("Failed to parse line: {0!s}".format(line), lineNumber)
vobject.base.ParseError: At line 7: Failed to parse line: =45=50;;;
svilendobrev commented 3 years ago

instead of waiting for the library to be fixed... Seems most/android phone exporters split long lines (>115) this way - ending on '=' then next line starts with '='. Most non-ascii names hit this limit easily.

newvcardtext = vcardtext.replace( '=\n=', '=') works fine joining them back; use on single vcard or over whole vcf file/text, before parsing with vobject.

Volker-Weissmann commented 3 years ago

Thank you, this works.

elig0n commented 2 years ago

You must allow QP decoding since the parser knows how to decode it:

print(vobject.readOne(el, allowQP=True))
Volker-Weissmann commented 2 years ago

print(vobject.readOne(el, allowQP=True))

This also works.