Fix undef boolean attributes#36
Conversation
e801ff8 to
864523f
Compare
… attribute name - but see #17 discussion
This was likely set to fail for debugging purposes
864523f to
4175e31
Compare
Code Review: PR #36 — Fix undef boolean attributesSummaryThe PR aims to align Critical (must fix before merge)C1.
|
Introduces a new strict_boolean_attributes option (off by default) that
controls whether attributes without values should be reported as undef.
When off (the default), the historic name-as-value behavior is preserved
so existing consumers see no change. When on, only attributes listed as
boolean by the HTML Living Standard get the name-as-value treatment;
everything else is reported as undef.
Code changes (hparser.c):
- Replace the open-coded byte-by-byte compare with strnEQx() from util.c.
- Fix an uninitialized-SV bug in the prior loop: found=1 was set inside
the per-character compare, so a length-collision with a partial char
match (e.g. <x dxsabled>) would skip both the full-match assignment
AND the fallback newSV(0), passing an uninitialized SV* downstream.
- Move attribute matching into a reusable is_boolean_attribute() helper
and call it from both ARG_ATTR and ARG_TOKENS paths so behavior is
consistent across argspecs.
- Use static const ordering, BOOL_ATTR(s) macro with sizeof()-1, and
re-source the list from the HTML Living Standard (adds defer, inert,
shadowroot*, plus the HTML4 legacy nowrap/compact/noresize/noshade;
drops the non-standard allowpaymentrequest).
- Restore consistent tab indentation in the boolean branch.
Wiring:
- Add bool strict_boolean_attributes to struct p_state in hparser.h.
- Copy it in dup_pstate for ithreads.
- Expose via the existing ALIAS-driven boolean accessor in Parser.xs.
Tests:
- Revert prior expectation changes in t/cases.t, t/msie-compat.t and
t/parser.t now that default behavior is preserved.
- Add t/strict-boolean-attributes.t exercising the new option:
accessor semantics, default-mode preservation, strict-mode happy
path, regression coverage for the uninitialized-SV bug, ASCII
case-insensitive matching, boolean_attribute_value interaction,
smoke test of every entry, and the ARG_TOKENS path.
Docs:
- Document strict_boolean_attributes in the methods POD and reference
it from the attr/tokens argspec descriptions.
- Add a Changes entry under {{$NEXT}} pointing to GH#17/GH#36.
Refs GH#17, GH#36.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Both are listed as boolean attributes in the current HTML Living Standard (on <video> and <audio>/<video> respectively) but were missing from the table. Picked up in second-pass review. Also clarifies the message on a length-collision regression test that was confusingly worded. Refs GH#17, GH#36. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Code Review (Round 2) — PR #36What was done well
CriticalNone. ImportantI1 (FIXED in follow-up commit e4bc5e3)
MinorM1 —
|
Summary
Adds a new opt-in
strict_boolean_attributesoption (off by default) that controls how attributes without values are reported instartevents. When enabled, only attributes that the HTML Living Standard defines as boolean (e.g.checked,disabled,selected,defer,inert) are reported with their name as the value; every other value-less attribute is reported asundef.The default remains the historic name-as-value behavior, so existing consumers see no change.
Fixes #17.
Behavior
The option affects both the
attrandtokensargspecs. Matching against the spec list is ASCII case-insensitive (<input CHECKED>still matches).boolean_attribute_valuestill applies to recognized boolean attributes; non-boolean value-less attributes always becomeundefregardless of that setting.Boolean attribute list
Sourced from the HTML Living Standard plus a few HTML4 legacy entries still found in the wild:
allowfullscreen,async,autofocus,autoplay,checked,compact,controls,default,defer,disabled,formnovalidate,hidden,inert,ismap,itemscope,loop,multiple,muted,nomodule,noresize,noshade,novalidate,nowrap,open,playsinline,readonly,required,reversed,selected,shadowrootclonable,shadowrootdelegatesfocus,shadowrootserializable,truespeedallowpaymentrequestis intentionally excluded (removed from the spec).Implementation notes
is_boolean_attribute()helper inhparser.cusesstrnEQx()fromutil.cfor the case-insensitive comparison; the spec list is astatic consttable with aBOOL_ATTR(s)macro that derives lengths fromsizeof(s) - 1so the array stays consistent on edits.ARG_ATTRandARG_TOKENSpaths share the helper so the two argspecs agree in strict mode.Parser.xsand copied indup_pstatefor ithreads.Test plan
make test— all 51 test files, 526 subtests pass on perl 5.42.t/strict-boolean-attributes.tcovers:attrandtokens.<x dxsabled>(length matchesdisabled, content differs after first char) now correctly resolve toundef.boolean_attribute_valueinteraction in both modes.