google / iconvg

IconVG is a compact, binary format for simple vector graphics: icons, logos, glyphs and emoji.
Apache License 2.0
676 stars 11 forks source link

Metadata block error conditions underdefined #11

Closed Hixie closed 2 years ago

Hixie commented 3 years ago

It's not clear if it's legal for data in a metadata block to extend past the end of itself.

For example, consider a situation where the metadata section has a block declared with length 0. The byte after the length gives the MID. Suppose (for simplicity) that it's not recognized. That byte also then gives the first opcode of the file. Is that valid?

I can imagine (absurd) situations where an IconVG serializer finds ways to overlap data in this way to save a few bytes...

Similarly, is it valid for a metadata block to be too long? e.g. what if a MID=0 block has length 1024? Are the extra bytes just ignored, or is that an error?

Hixie commented 3 years ago

One thing to consider is that if it's possible to detect errors when you recognize the block, but not when you don't, then some files will be rendered "correctly" by less-capable clients, but rejected by more-capable clients. This will lead to clients ignoring the spec so as to render images that contain bogus metadata blocks which less capable clients handle fine.

Another thing to consider is that sometimes the parser may want to skip processing a known metadata block. For example, if the user provides a custom palette, the efficient way to parse the suggested palette metadata block is to skip it entirely. This means that if there's any errors that can be detected by parsing that block, then an image may render fine when a custom palette is provided, and fail to render when one is not provided, even if the image does nothing with the custom palette.

Hixie commented 3 years ago

Here's a specific case that may already trip up implementations today (I haven't checked):

Imagine a file that has a suggested palette metadata block, whose size is smaller than the actual palette described, and whose actual palette, if the implementation tries to read it, goes past the end of the file.

An implementation that skips that block (e.g. because a custom palette has been provided by the user) will render the file, but an implementation that does not (e.g. because it always reads it, or because no custom palette was provided by the user) may fail due to the unexpected end of file (or metadata block).