open-standards/wai/vector-conformance/vectors/refusals/index.json
Transaction Science 10ba6e9bcc wai-vector: the text layer and section 5, text and accessibility (D7-7)
graphics-vector.md section 5 (Draft): what a sink exposes to assistive
technology and to a text consumer, and how. Each text block's active set (the
effective windows of the items that draw it, merged), the projection at a
frame and the transcript as exact JSON, the text record and its digest, ruby,
purposes, writing modes and the cluster rule.

- wai-vector: src/text.rs (no_std, no dependency), the a11y and text commands,
  and vectors verify recomputing every text record.
- The corpus: a new a11y group, each payload with its text record
  (<name>.a11y.jsonl) and its digest in the expected file; canonical and
  refusal vectors for TEXT. No existing expected file changes.
- tests/text_layer.rs: each rule of section 5, with expected JSON written by
  hand from the text, each falsified once.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 02:43:02 -04:00

215 lines
16 KiB
JSON

{
"attack-d-2-held-sets":"two held sets of 2^25 bytes: held_len = 2^26, within the cap; the sink holds neither -> outline_not_held",
"attack-d-3-held-sets":"three held sets of 2^25 bytes: held_len = 3 * 2^25 > 2^26 -> too_large",
"attack-d-64-held-sets":"review A, attack D: 64 held sets of the largest WOS1 (held_len past 2^26) -> too_large",
"attack-e-duplicate-tracks":"review A, attack E, scaled: 512 tracks equal but for their last key, two of them equal -> payload_malformed, found by sorting",
"rich":"the payload the record-level vectors patch: accepted",
"s1-format":"step 1: format 2 -> payload_malformed",
"s1-magic":"step 1: magic -> payload_malformed",
"s1-magic-before-cap":"pair: a bad magic and n_sizes past its cap -> payload_malformed (step 1 before step 2)",
"s1-short":"step 1: fewer than 80 bytes, no readable header -> payload_malformed",
"s1-zero":"step 1: the header's zero field -> payload_malformed",
"s2-cap-before-length":"pair: n_rates past its cap and a trailing byte -> too_large (step 2 before step 3)",
"s2-cap-before-range":"pair: n_items = 0 (a step 4 range) and n_keys past its cap -> too_large (step 2 before step 4)",
"s2-cap-held_len":"step 2: held_len one past its cap -> too_large",
"s2-cap-inline_len":"step 2: inline_len one past its cap -> too_large",
"s2-cap-n_clusters":"step 2: n_clusters one past its cap -> too_large",
"s2-cap-n_glyphs":"step 2: n_glyphs one past its cap -> too_large",
"s2-cap-n_items":"step 2: n_items one past its cap -> too_large",
"s2-cap-n_keys":"step 2: n_keys one past its cap -> too_large",
"s2-cap-n_paints":"step 2: n_paints one past its cap -> too_large",
"s2-cap-n_paths":"step 2: n_paths one past its cap -> too_large",
"s2-cap-n_rates":"step 2: n_rates one past its cap -> too_large",
"s2-cap-n_sets":"step 2: n_sets one past its cap -> too_large",
"s2-cap-n_sizes":"step 2: n_sizes one past its cap -> too_large",
"s2-cap-n_tables":"step 2: n_tables one past its cap -> too_large",
"s2-cap-path_contours":"step 2: path_contours one past its cap -> too_large",
"s2-cap-path_points":"step 2: path_points one past its cap -> too_large",
"s2-cap-strings_len":"step 2: strings_len one past its cap -> too_large",
"s2-exact-length":"step 2: every count within its cap, the computed exact length above 2^26 -> too_large",
"s2-sets-total":"step 2: inline_len + held_len = 2^26 + 1, each within its own cap -> too_large",
"s3-trailing-byte":"step 3: one trailing byte -> payload_malformed",
"s3-truncated":"step 3: one byte short -> payload_malformed",
"s4-cluster-zero":"CLUSTER zero field -> payload_malformed",
"s4-design-h-large":"step 4, the header: design_h = 4097 -> field_range",
"s4-design-w-before-h":"step 4, the header: both design sides -> field_range",
"s4-design-w-small":"step 4, the header: design_w = 15 -> field_range",
"s4-dur-over":"step 4, the header: t0 + dur = 2^31 + 1 -> field_range",
"s4-dur-zero":"step 4, the header: dur = 0 -> field_range",
"s4-glyph-x":"GLYPH.x = 2^23 -> field_range",
"s4-glyph-y":"GLYPH.y = -2^23 - 1 -> field_range",
"s4-glyph-zero":"GLYPH zero field -> payload_malformed",
"s4-header-before-record":"pair: dur = 0 and an ITEM.kind = 7 -> field_range (the header first)",
"s4-item-clusters-over":"a run with n_clusters = 8193 -> field_range",
"s4-item-end-slot":"a group end's slot other than 0 -> field_range",
"s4-item-glyphs-path":"a path fill with n_glyphs = 1 -> field_range",
"s4-item-glyphs-run-over":"a run with n_glyphs = 4097 -> field_range",
"s4-item-glyphs-run-zero":"a run with n_glyphs = 0 -> field_range",
"s4-item-kind-four":"pair: ITEM.kind = 4 with ref = 0, and an inline set marked held (a step 5(a) sum) -> field_range (the record pass first)",
"s4-item-matrix-begin":"a group begin with a matrix slot -> field_range",
"s4-item-paint-begin":"a group begin's paint other than 0xFFFF -> field_range",
"s4-item-paint-end":"a group end's paint other than 0 -> field_range",
"s4-item-ref-path":"a path fill's ref = n_paths -> field_range",
"s4-item-ref-set":"a run's ref = n_sets -> field_range",
"s4-item-rule-before-zero2":"pair: rule out of range then zero@2 -> field_range (offset order)",
"s4-item-rule-no-clip":"a group begin with no clip and rule 1 -> field_range (at ref)",
"s4-item-rule-path":"ITEM.rule = 2 on a path fill -> field_range",
"s4-item-rule-run":"ITEM.rule = 1 on a run -> field_range",
"s4-item-slot-range":"a slot naming track n_tracks -> field_range",
"s4-item-t-off-order":"ITEM.t_off = t_on -> field_range",
"s4-item-t-off-over":"ITEM.t_off = 2^31 + 1 -> field_range",
"s4-item-t-on":"ITEM.t_on = 2^31 -> field_range",
"s4-item-text-path":"a path fill's text = n_texts -> field_range",
"s4-item-text-run":"a run's text 0xFFFF -> field_range",
"s4-item-unit-scale-clip":"a group begin with a clip and unit_scale = 0 -> field_range",
"s4-item-unit-scale-over":"unit_scale = 2^24 + 1 -> field_range",
"s4-item-unit-scale-zero":"a path fill's unit_scale = 0 -> field_range",
"s4-item-zero10":"ITEM zero@10 -> payload_malformed",
"s4-item-zero2":"ITEM zero@2 -> payload_malformed",
"s4-item-zero2-before-ref":"pair: zero@2 then ref out of range -> payload_malformed (offset order)",
"s4-item-zero42":"ITEM zero@42 -> payload_malformed",
"s4-key-interp":"KEY.interp = 2 + 1 with one table -> field_range",
"s4-key-interp-before-sum":"pair: KEY.interp = 2 + j with j >= n_tables, and an inline set marked held (a step 5(a) sum) -> field_range (the index range is the record pass's)",
"s4-key-t":"KEY.t = 2^31 -> field_range",
"s4-key-zero":"KEY zero field -> payload_malformed",
"s4-n-items-zero":"step 4: n_items = 0 -> field_range",
"s4-n-rates-zero":"step 4: n_rates = 0 -> field_range",
"s4-n-sizes-zero":"step 4: n_sizes = 0 -> field_range",
"s4-paint-over-alpha":"PAINT r > a -> field_range",
"s4-path-before-text":"pair: a PATH zero field and TEXT.purpose = 0 -> payload_malformed (tables in file order: PATHS before TEXTS)",
"s4-path-contours-over-points":"PATH.n_contours above n_points -> field_range",
"s4-path-n-contours-zero":"PATH.n_contours = 0 -> field_range",
"s4-path-n-points-zero":"PATH.n_points = 0 -> field_range",
"s4-path-point-tag":"PATH_POINT.tag = 3 -> field_range",
"s4-path-points-limit":"PATH.n_points = 16,384 -> points_limit",
"s4-path-points-limit-before-zero":"pair: n_points = 16,384 then a zero field -> points_limit (offset order)",
"s4-path-zero":"PATH zero field -> payload_malformed",
"s4-rate-den-zero":"RATE.den = 0 -> field_range",
"s4-rate-gcd":"RATE 50/2: gcd 2 -> field_range",
"s4-rate-num-zero":"RATE.num = 0 -> field_range",
"s4-rate-over-240":"RATE 241/1 above 240 fps -> field_range",
"s4-rate-p-not-integral":"RATE 7/1 at tb = 120000: P not an integer -> field_range",
"s4-set-carriage":"SET.carriage = 2 -> field_range",
"s4-set-carriage-before-zero":"pair: carriage = 2 then a zero field -> field_range (offset order)",
"s4-set-length-large":"SET.length = 2^25 + 1 -> field_range",
"s4-set-length-small":"SET.length = 31 -> field_range",
"s4-set-zero":"SET zero field -> payload_malformed",
"s4-set-zero-before-length":"pair: a zero field then length = 31 -> payload_malformed (offset order)",
"s4-size-aspect":"SIZE.h off the design aspect -> field_range",
"s4-size-w-over-4x":"SIZE.w above 4 * design_w -> field_range",
"s4-size-w-small":"SIZE.w = 15 -> field_range",
"s4-size-w-under-8th":"SIZE.w below design_w / 8 -> field_range",
"s4-t0-before-dur":"step 4, the header: t0 = 2^31 and dur = 0 -> field_range",
"s4-t0-over":"step 4, the header: t0 = 2^31 -> field_range",
"s4-table-e0":"TABLE E[0] = 1 -> field_range",
"s4-table-e16":"TABLE E[16] = 65535 -> field_range",
"s4-table-over":"TABLE E[5] = 65537 -> field_range",
"s4-tb-before-record":"step 4, the header: tb = 0 -> field_range",
"s4-tb-not-divisible":"step 4, the header: tb = 119,999 (a header value in range; the RATE's P is not an integer) -> field_range at RATE.den",
"s4-tb-over":"step 4, the header: tb = 2^20 + 1 -> field_range",
"s4-tb-zero":"step 4, the header: tb = 0 -> field_range",
"s4-text-before-item":"pair: TEXT.mode = 3 and an ITEM zero field -> field_range (tables in file order: TEXTS before ITEMS)",
"s4-text-dir":"TEXT.dir = 2 -> field_range",
"s4-text-lang-len-over":"TEXT.lang_len = 64 -> field_range",
"s4-text-lang-len-zero":"TEXT.lang_len = 0 -> field_range",
"s4-text-mode":"TEXT.mode = 3 -> field_range",
"s4-text-purpose-zero":"TEXT.purpose = 0 -> field_range",
"s4-text-ruby-len-no-ruby":"TEXT.ruby_len = 1 with no ruby -> field_range",
"s4-text-ruby-len-zero":"TEXT ruby set with ruby_len = 0 -> field_range",
"s4-text-ruby-over":"TEXT.ruby above n_texts -> field_range",
"s4-text-ruby-start":"TEXT.ruby_start with no ruby -> field_range",
"s4-text-str-len-over":"TEXT.str_len = 4097 -> field_range",
"s4-text-str-len-zero":"TEXT.str_len = 0 -> field_range",
"s4-track-kind-four":"TRACK.kind = 4 -> field_range",
"s4-track-kind-zero":"TRACK.kind = 0 -> field_range",
"s4-track-n-keys-over":"TRACK.n_keys = 4097 -> field_range",
"s4-track-n-keys-zero":"TRACK.n_keys = 0 -> field_range",
"s4-track-zero":"TRACK zero field -> payload_malformed",
"s5a-clusters-sum":"5(a), new: a CLUSTER no run owns -> payload_malformed",
"s5a-glyphs-sum":"5(a), new: a GLYPH no run owns -> payload_malformed",
"s5a-held-sum":"5(a): held_len = 32 with no held set -> payload_malformed",
"s5a-inline-sum":"5(a): an inline set marked held: the inline lengths do not sum to inline_len -> payload_malformed",
"s5a-path-contours-sum":"5(a), new: a PATH_END no path owns -> payload_malformed",
"s5a-path-points-sum":"5(a), new: a PATH_POINT no path owns -> payload_malformed",
"s5a-strings-sum":"5(a), new: a STRINGS byte no block owns -> payload_malformed",
"s5a-sum-before-typing":"pair: a sum rule and an opacity key of 256 -> payload_malformed (5(a) before 5(c))",
"s5a-track-keys-sum":"5(a): a KEY no track owns -> payload_malformed",
"s5b-keys-order":"5(b): two keys of a track at one tick -> payload_malformed",
"s5b-last-key-interp":"5(b): a track's last key with interp 1 -> payload_malformed",
"s5b-rates-order":"5(b): RATEs not ascending -> payload_malformed",
"s5b-sizes-equal":"5(b): two SIZEs of one width -> payload_malformed",
"s5b-sizes-order":"5(b): SIZEs not ascending by w -> payload_malformed",
"s5c-matrix-key":"5(c): a matrix key of 2^20 + 1 -> field_range",
"s5c-opacity-key":"5(c): an opacity key of 256 -> field_range",
"s5c-slot-kind":"5(c): a matrix slot naming an opacity track -> field_range",
"s5c-translation-key":"5(c): a translation key of 2^22 + 1 -> field_range",
"s5c-typing-before-groups":"pair: an opacity key of 256 and a group left open -> field_range (5(c) before 5(d))",
"s5c-typing-before-strings":"pair: an opacity key of 256 and a language tag with a leading hyphen -> field_range (5(c) before 5(f))",
"s5d-depth-five":"5(d): groups nested five deep -> payload_malformed",
"s5d-end-first":"5(d): a group end with no group open -> payload_malformed",
"s5d-open":"5(d): a group open after the last item -> payload_malformed",
"s5e-box":"5(e): a path box one unit too wide -> payload_malformed",
"s5e-ends-last":"5(e): a path's last contour end below n_points - 1 -> payload_malformed",
"s5e-ends-order":"5(e): contour ends not increasing -> payload_malformed",
"s5e-grammar":"5(e): a contour whose first point is a control -> payload_malformed",
"s5e-grammar-two-quads":"5(e): two quadratic controls in a row (implied points are stored) -> payload_malformed",
"s5f-string-c0":"5(f): a C0 control U+0001 -> payload_malformed",
"s5f-string-c1":"5(f): a C1 control U+0085 -> payload_malformed",
"s5f-string-del":"5(f): U+007F -> payload_malformed",
"s5f-string-newline":"5(f): U+000A is the one C0 control allowed: accepted",
"s5f-string-overlong":"5(f): an overlong encoding -> payload_malformed",
"s5f-string-surrogate":"5(f): an encoded surrogate -> payload_malformed",
"s5f-string-utf8":"5(f): a byte that is not UTF-8 -> payload_malformed",
"s5f-tag-double-hyphen":"5(f): a doubled hyphen -> payload_malformed",
"s5f-tag-leading-hyphen":"5(f): a language tag with a leading hyphen -> payload_malformed",
"s5f-tag-trailing-hyphen":"5(f): a trailing hyphen -> payload_malformed",
"s5f-tag-underscore":"5(f): an underscore -> payload_malformed",
"s5g-block-before-sets":"pair: a block no run or path names, and a held set the sink cannot obtain -> payload_malformed (5(g) before 6)",
"s5h-decorative-before-sets":"pair: a path whose text alternative is a decorative block, and a held set the sink cannot obtain -> payload_malformed (5(h) before 6)",
"s6-held-malformed":"6: a held set that hashes right and is not a valid WOS1 -> outline_malformed",
"s6-held-not-held":"6: a held set the sink cannot obtain -> outline_not_held",
"s6-held-one-byte-longer":"6: a held set one byte longer than its length; the sink reads at most length + 1 bytes -> outline_mismatch",
"s6-held-shorter":"6: a held set one byte shorter than its length -> outline_mismatch",
"s6-inline-hash":"6: an inline set whose bytes do not hash to its record -> outline_mismatch",
"s6-inline-malformed":"6: an inline set with a bad magic -> outline_malformed",
"s6-inline-points-limit":"6: an inline set with a glyph of 16,384 points -> points_limit",
"s6-inline-too-large":"6: an inline set with n_glyphs past its cap -> too_large",
"s6-order-held-first":"pair: set 0 not held, set 1 malformed -> outline_not_held (sets in SET order)",
"s6-order-inline-first":"pair: set 0 malformed, set 1 not held -> outline_malformed (each set's checks before the next set)",
"s7-before-geometry":"pair: a missing glyph and a glyph far off the canvas -> glyph_missing (step 7 before step 8)",
"s7-glyph-missing":"7: a glyph record whose gid the run's set lacks -> glyph_missing",
"wos1-box":"check 10: a glyph box one unit too tall -> outline_malformed",
"wos1-box-empty-glyph":"check 10: a glyph with no points and a nonzero box -> outline_malformed",
"wos1-cap-before-length":"pair: n_glyphs past its cap and a trailing byte -> too_large (check 2 before 3)",
"wos1-contours-cap":"check 2: contours_total = 2^22 + 1 -> too_large",
"wos1-contours-over-points":"check 4: n_contours above n_points -> outline_malformed",
"wos1-ends-last":"check 7: the last contour end below n_points - 1 -> outline_malformed",
"wos1-ends-order":"check 7: contour ends not increasing -> outline_malformed",
"wos1-flags":"check 1: a reserved flag bit -> outline_malformed",
"wos1-format":"check 1: format 2 -> outline_malformed",
"wos1-gid-order":"check 5: gids not strictly increasing -> outline_malformed",
"wos1-glyph-zero":"check 4: a glyph record's zero field -> outline_malformed",
"wos1-grammar":"check 9: three cubic controls in a row -> outline_malformed",
"wos1-grammar-one-point-control":"check 9: a one-point contour whose point is a control (P_0 is on-curve in every contour) -> outline_malformed",
"wos1-length":"check 3: one trailing byte -> outline_malformed",
"wos1-magic":"check 1: magic -> outline_malformed",
"wos1-n-glyphs-cap":"check 2: n_glyphs = 65,537 -> too_large",
"wos1-n-glyphs-zero":"check 2: n_glyphs = 0 -> outline_malformed",
"wos1-notes-cap":"check 2: notes_len = 2^20 + 1 -> too_large",
"wos1-notes-utf8":"check 11: notes that end inside a UTF-8 sequence -> outline_malformed",
"wos1-notes-zero":"check 2: notes_len = 0 -> outline_malformed",
"wos1-points-16383":"check 4: a glyph of exactly 16,383 points: accepted",
"wos1-points-16384":"check 4: the same glyph with one more point, 16,384 -> points_limit",
"wos1-points-cap":"check 2: points_total = 2^22 + 1 -> too_large",
"wos1-points-limit":"check 4: a glyph of 16,384 points -> points_limit",
"wos1-points-limit-before-gid-order":"pair: a glyph of 16,384 points and gids out of order -> points_limit (check 4 before check 5)",
"wos1-points-limit-before-zero":"pair: one glyph with 16,384 points and a zero field -> points_limit (n_points first within a record)",
"wos1-points-no-contour":"check 4: points and no contour -> outline_malformed",
"wos1-set-a":"an outline set with lines, quadratics, cubics, a hole, an empty glyph and a one-point contour: accepted",
"wos1-short":"check 1: fewer than 32 bytes -> outline_malformed",
"wos1-sums":"check 6: n_points not summing to points_total -> outline_malformed",
"wos1-tag":"check 8: a tag of 3 -> outline_malformed",
"wos1-zero":"check 1: the zero field -> outline_malformed",
"wos1-zero-before-points-limit":"pair: glyph 0's zero field and glyph 1's 16,384 points -> outline_malformed (records in order)",
"wos1-zero-glyphs-before-points-cap":"pair: n_glyphs = 0 then points_total past its cap -> outline_malformed (field order)"
}