Fix parser/serializer bugs found by AFL fuzzing
Serializer fixes:
- Add leading newline preservation for pre, textarea, and listing elements.
Per HTML5 spec, the parser strips a single leading newline after these
element tags, so the serializer must emit an extra newline to preserve
content that starts with a newline.
- Escape < in attribute values to prevent tag injection during reparsing
Parser fix:
- Reset ignore_lf flag when any element is inserted, not just on character
tokens. Per HTML5 spec, only the immediately next token after
pre/textarea/listing should be checked for leading LF, but we were
persisting the flag across element insertions.
Tokenizer fix:
- Handle < in tag names per HTML5 spec: emit parse error and reconsume
in tag open state. Previously < was incorrectly added to tag names.
These fixes improve roundtrip stability for edge cases with:
- Pre-formatted elements with nested elements and leading newlines
- Attribute values containing < characters
- Malformed HTML with < inside tag names
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>