unified-font-object / ufoNormalizer

A tool that will normalize the XML and other data inside of a UFO.
Other
51 stars 19 forks source link

lib value can be an empty string #45

Closed typemytype closed 6 years ago

typemytype commented 6 years ago

this fails now...

import ufonormalizer

d = """<?xml version="1.0" encoding="UTF-8"?>
<glyph name="test" format="1">
<lib>
    <dict>
        <key>test</key>
        <string></string>
    </dict>
</lib>
</glyph>
"""

print(ufonormalizer.normalizeGLIFString(d))

results in

<?xml version="1.0" encoding="UTF-8"?>
<glyph name="test" format="1">
    <lib>
        <dict>
            <key>test</key>
        </dict>
    </lib>
</glyph>

see https://github.com/unified-font-object/ufoNormalizer/blob/master/src/ufonormalizer.py#L1092-L1093

element.text can be None, but must maybe converted to an empty string when the tag is string

typemytype commented 6 years ago

I can make a PR to solve this.

It is possible this also affects the "data" tag, as this also could be empty

madig commented 6 years ago

Solved at least for strings by #48.

madig commented 6 years ago

It does indeed have the same problem, but it blows up instead:

_______________ UFONormalizerTest.test_normalizeGLIF_lib_defined _______________

self = <tests.test_ufonormalizer.UFONormalizerTest testMethod=test_normalizeGLIF_lib_defined>

    def test_normalizeGLIF_lib_defined(self):
        e = '''
            <lib>
                <dict>
                    <key>foo</key>
                    <string>bar</string>
                    <key>abc</key>
                    <string></string>
                    <key>def</key>
                    <data/>
                </dict>
            </lib>
            '''.strip()
        element = ET.fromstring(e)
        writer = XMLWriter(declaration=None)
>       _normalizeGlifLib(element, writer)

tests/test_ufonormalizer.py:765:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src/ufonormalizer.py:749: in _normalizeGlifLib
    obj = _convertPlistElementToObject(element[0])
src/ufonormalizer.py:1091: in _convertPlistElementToObject
    obj[key] = _convertPlistElementToObject(subElement)
src/ufonormalizer.py:1097: in _convertPlistElementToObject
    return plistlib.Data.fromBase64(element.text)
/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/plistlib.py:220: in fromBase64
    return cls(_decode_base64(data))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

s = None

    def _decode_base64(s):
        if isinstance(s, str):
            return binascii.a2b_base64(s.encode("utf-8"))

        else:
>           return binascii.a2b_base64(s)
E           TypeError: argument should be bytes, buffer or ASCII string, not 'NoneType'

/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/plistlib.py:274: TypeError
anthrotype commented 6 years ago

sure we can handle that if we like, but I don't see any real-world use cases for deliberately wanting to set a plist <data> element to an empty element..

madig commented 6 years ago

Yes, but while we're at it... you never know.

anthrotype commented 6 years ago

ok

anthrotype commented 6 years ago

fixed by #49