svg_conform 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.github/workflows/rake.yml +3 -0
- data/Gemfile +7 -3
- data/Gemfile.lock +272 -0
- data/TODO.issue-100/00-overview.md +135 -0
- data/TODO.issue-100/01-build-lens-core-v1.md +92 -0
- data/TODO.issue-100/02-adopt-lens-core-in-svg.md +123 -0
- data/TODO.issue-100/03-ship-svg-1-1-full-static.md +138 -0
- data/TODO.issue-100/04-ship-svg-2-secure-static.md +131 -0
- data/TODO.issue-100/05-freeze-candidate-and-handoff.md +108 -0
- data/TODO.issue-100/90-progress.md +65 -0
- data/config/profiles/metanorma.yml +3 -3
- data/config/profiles/svg_1_1_full_static.yml +69 -0
- data/config/profiles/svg_2_secure_static.yml +55 -0
- data/config/requirements/processing_features_static.yml +29 -0
- data/data/svg_1_1/manifest.yml +7 -0
- data/data/svg_1_1/svg11-flat-20110816.dtd +5664 -0
- data/docs/api_reference.adoc +19 -1
- data/docs/cli_guide.adoc +35 -45
- data/docs/diagnostics.adoc +73 -0
- data/docs/lens_core_handoff.adoc +84 -0
- data/docs/profiles.adoc +94 -1
- data/lib/svg_conform/cli.rb +3 -3
- data/lib/svg_conform/commands/check.rb +11 -60
- data/lib/svg_conform/conformance_report.rb +79 -1
- data/lib/svg_conform/diagnostics/lens_core_adapter.rb +200 -0
- data/lib/svg_conform/document.rb +12 -1
- data/lib/svg_conform/node_helpers.rb +1 -1
- data/lib/svg_conform/profile.rb +11 -2
- data/lib/svg_conform/quality_metrics/complexity_calculator.rb +3 -3
- data/lib/svg_conform/references/base_reference.rb +153 -0
- data/lib/svg_conform/report_comparator.rb +4 -4
- data/lib/svg_conform/requirements/base_requirement.rb +6 -0
- data/lib/svg_conform/requirements/external_references_requirement.rb +234 -0
- data/lib/svg_conform/requirements/link_validation_requirement.rb +2 -0
- data/lib/svg_conform/requirements/processing_features_requirement.rb +175 -0
- data/lib/svg_conform/requirements/svg_1_1_document_requirement.rb +213 -0
- data/lib/svg_conform/requirements.rb +6 -0
- data/lib/svg_conform/sax_document.rb +8 -4
- data/lib/svg_conform/sax_validation_handler.rb +22 -1
- data/lib/svg_conform/validation/css2_core_grammar.rb +359 -0
- data/lib/svg_conform/validation/css_references.rb +122 -0
- data/lib/svg_conform/validation/error_tracker.rb +3 -1
- data/lib/svg_conform/validation/svg_1_1_document_conformance.rb +155 -0
- data/lib/svg_conform/validation_context.rb +25 -5
- data/lib/svg_conform/validation_result.rb +91 -16
- data/lib/svg_conform/version.rb +1 -1
- data/lib/svg_conform.rb +24 -0
- data/spec/fixtures/diagnostics/external-reference-info.svg +6 -0
- data/spec/fixtures/plantuml/README.adoc +11 -0
- data/spec/fixtures/plantuml/unit-type.svg +1 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/animation.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/css-grammar.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/dtd-attribute.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/dtd-content-model.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/interaction.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/malformed-xml.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/script.svg +5 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/wrong-namespace.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/wrong-version.svg +4 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/invalid/xml-stylesheet.svg +5 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/valid/css.svg +5 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/valid/foreign-metadata.svg +6 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/valid/minimal-full.svg +5 -0
- data/spec/fixtures/profiles/svg_1_1_full_static/valid/xml-stylesheet.svg +5 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/animation.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/css-import.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/css-url.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/data-bad-png.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/data-empty-png.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/data-malformed-base64.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/data-malformed-percent.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/data-unsupported-type.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/file-like-fragment.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/http.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/https.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/interaction.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/protocol-relative.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/relative-file-fragment.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/relative-file.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/script.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/svg-data-excessive-nesting.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/svg-data-malformed-xml.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/svg-data-nested-external.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/urn.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/invalid/xml-stylesheet.svg +5 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/jpeg-base64.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/jpeg-percent.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/png-base64.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/png-percent.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/same-document-fragment.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/svg-base64.svg +4 -0
- data/spec/fixtures/profiles/svg_2_secure_static/valid/svg-percent.svg +4 -0
- data/spec/svg_conform/commands/check_command_spec.rb +22 -2
- data/spec/svg_conform/commands/profiles_command_spec.rb +18 -0
- data/spec/svg_conform/conformance_report_spec.rb +90 -0
- data/spec/svg_conform/diagnostics/lens_core_adapter_spec.rb +136 -0
- data/spec/svg_conform/gemspec_spec.rb +21 -0
- data/spec/svg_conform/profiles/svg_1_1_full_static_profile_spec.rb +146 -0
- data/spec/svg_conform/profiles/svg_2_secure_static_profile_spec.rb +150 -0
- data/spec/svg_conform/profiles_plantuml_spec.rb +81 -0
- data/spec/svg_conform/references/data_uri_reference_spec.rb +97 -0
- data/spec/svg_conform/references/integration_spec.rb +30 -0
- data/spec/svg_conform/references/reference_classifier_spec.rb +17 -0
- data/spec/svg_conform/requirements/external_references_requirement_spec.rb +109 -0
- data/spec/svg_conform/requirements/link_validation_requirement_spec.rb +16 -0
- data/spec/svg_conform/requirements/processing_features_requirement_spec.rb +75 -0
- data/spec/svg_conform/requirements/svg_1_1_document_requirement_spec.rb +141 -0
- data/spec/svg_conform/validation/css2_core_grammar_spec.rb +116 -0
- data/spec/svg_conform/validation/svg_1_1_document_conformance_spec.rb +144 -0
- data/spec/svg_conform/validation_context_source_plumbing_spec.rb +122 -0
- data/spec/svg_conform/validation_context_spec.rb +39 -0
- data/spec/svg_conform/validation_result_spec.rb +123 -0
- data/svg_conform.gemspec +3 -2
- metadata +102 -6
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# 03 — Ship SVG 1.1 Full/static
|
|
2
|
+
|
|
3
|
+
Effort: **8–12 person-days**
|
|
4
|
+
|
|
5
|
+
Repository: `claricle/svg_conform`
|
|
6
|
+
|
|
7
|
+
Depends on: Card 02
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Add an opt-in profile for SVG 1.1 Full documents under static processing. The
|
|
12
|
+
profile validates the Recommendation's document grammar instead of treating an
|
|
13
|
+
element allow-list as standards conformance, and it behaves the same through
|
|
14
|
+
the repository's DOM and SAX entry points.
|
|
15
|
+
|
|
16
|
+
## Requirement matrix
|
|
17
|
+
|
|
18
|
+
Add `config/profiles/svg_1_1_full_static.yml` with this stable matrix. Every
|
|
19
|
+
entry carries its listed normative URI and emits an error with its own ID.
|
|
20
|
+
|
|
21
|
+
| Requirement ID | Rule | Normative citation |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `svg11.document.xml` | The source is well-formed XML and exposes its original declaration, doctype, and processing instructions to document-level validation. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGDocuments` |
|
|
24
|
+
| `svg11.document.root` | The document element is `svg` in `http://www.w3.org/2000/svg`. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#SVGElement` |
|
|
25
|
+
| `svg11.document.version` | The root declares SVG version `1.1`. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#SVGElementVersionAttribute` |
|
|
26
|
+
| `svg11.document.grammar` | After the Appendix G.2 foreign-namespace transform, elements, attributes, content models, and required values validate against the pinned SVG 1.1 Full flat DTD. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGDocuments` |
|
|
27
|
+
| `svg11.document.css2` | Style attributes and style sheets accepted by the document conform to the CSS 2 core grammar required by SVG 1.1; this checks syntax, not browser rendering or every CSS property semantic. | `https://www.w3.org/TR/2008/REC-CSS2-20080411/grammar.html` |
|
|
28
|
+
| `svg11.document.xml_stylesheet` | `xml-stylesheet` processing instructions obey their Recommendation's pseudo-attribute syntax and SVG applicability rules. | `https://www.w3.org/TR/1999/REC-xml-stylesheet-19990629/` |
|
|
29
|
+
| `svg11.processing.script` | Static mode rejects script elements and event-handler attributes. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers` |
|
|
30
|
+
| `svg11.processing.animation` | Static mode rejects SVG animation elements and animation-timing attributes. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers` |
|
|
31
|
+
| `svg11.processing.interaction` | Static mode rejects interaction-only event attributes and cursor behavior. | `https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers` |
|
|
32
|
+
|
|
33
|
+
The profile's `specification_uri` is the dated SVG 1.1 Second Edition
|
|
34
|
+
Recommendation. Profile and requirement citations flow into LensCore reports.
|
|
35
|
+
|
|
36
|
+
## Source-level validation plumbing
|
|
37
|
+
|
|
38
|
+
Document conformance needs bytes that parsed DOMs can discard. Add an optional
|
|
39
|
+
`source` and `source_path` to `ValidationContext`, retain the original content
|
|
40
|
+
in `Document`, and pass `SaxDocument#content` into `SaxValidationHandler`.
|
|
41
|
+
Extend `BaseRequirement` with a no-op
|
|
42
|
+
`validate_source(source, context)` hook. Invoke it exactly once before DOM
|
|
43
|
+
traversal or SAX element dispatch; source diagnostics then share the normal
|
|
44
|
+
tracker and LensCore adapter.
|
|
45
|
+
|
|
46
|
+
For `Document.from_node`, serialize the node and mark the source as serialized
|
|
47
|
+
so a source-sensitive requirement can report that a declaration/doctype/PI
|
|
48
|
+
claim cannot be proved instead of silently accepting it. File and string entry
|
|
49
|
+
points retain exact input bytes. Add focused parity specs for file and string
|
|
50
|
+
entry points in both modes.
|
|
51
|
+
|
|
52
|
+
## Validators and shared processing requirement
|
|
53
|
+
|
|
54
|
+
- Vendor the dated flat DTD at
|
|
55
|
+
`data/svg_1_1/svg11-flat-20110816.dtd`. Add
|
|
56
|
+
`data/svg_1_1/manifest.yml` with its W3C source URL, retrieval date, and
|
|
57
|
+
computed SHA-256. Resolution is local-only: external entity or network access
|
|
58
|
+
during validation is an error.
|
|
59
|
+
- Add `SvgConform::Validation::Svg11DocumentConformance` in
|
|
60
|
+
`lib/svg_conform/validation/svg_1_1_document_conformance.rb` and expose it
|
|
61
|
+
through `Svg11DocumentRequirement`. Implement the Appendix G.2 transform in
|
|
62
|
+
an isolated helper and validate the transformed copy; never rewrite the
|
|
63
|
+
caller's document.
|
|
64
|
+
- Add a focused CSS 2 core tokenizer/parser at
|
|
65
|
+
`lib/svg_conform/validation/css2_core_grammar.rb` and reuse it for style
|
|
66
|
+
attributes, style elements, and applicable stylesheet content. Keep property
|
|
67
|
+
support and rendering semantics outside this syntax check.
|
|
68
|
+
- Add `ProcessingFeaturesRequirement` in
|
|
69
|
+
`lib/svg_conform/requirements/processing_features_requirement.rb`. Its YAML
|
|
70
|
+
configuration names `script`, `animation`, and `interaction` categories and
|
|
71
|
+
their separate IDs/citations. Implement DOM and SAX paths once here. Card 04
|
|
72
|
+
consumes the same serialized requirement unchanged.
|
|
73
|
+
- Require both new requirement files from `lib/svg_conform/requirements.rb` and
|
|
74
|
+
include them in `SvgConform::Requirements.all`. The existing
|
|
75
|
+
`Profile::REQUIREMENTS_CLASS_MAP` discovers their files, and
|
|
76
|
+
`ProfileCompiler` loads and precomputes them; cover those existing mechanisms
|
|
77
|
+
in the profile spec rather than adding a competing registry.
|
|
78
|
+
|
|
79
|
+
### Open implementation question resolved by this card
|
|
80
|
+
|
|
81
|
+
Before building the grammar validator, run four tiny probes (valid document,
|
|
82
|
+
invalid content model, external-entity attempt, and Appendix G.2 foreign
|
|
83
|
+
content) against the currently bundled Moxml/Leptris stack. Record the result in
|
|
84
|
+
the validator spec. If that stack cannot perform offline validating-DTD checks,
|
|
85
|
+
select the smallest maintained Ruby-compatible validating XML library, add it
|
|
86
|
+
to `svg_conform.gemspec` and `Gemfile`, and lock it. Selection criteria are the
|
|
87
|
+
four probes, supported Ruby versions, no network/entity resolution, and no
|
|
88
|
+
shelling out. Do not substitute a hand-maintained element list for DTD
|
|
89
|
+
validation.
|
|
90
|
+
|
|
91
|
+
## Corpus, tests, and documentation
|
|
92
|
+
|
|
93
|
+
Create `spec/fixtures/profiles/svg_1_1_full_static/` with small fixtures that
|
|
94
|
+
isolate each matrix row:
|
|
95
|
+
|
|
96
|
+
- valid minimal Full, CSS, XML-stylesheet, and foreign-metadata documents;
|
|
97
|
+
- invalid malformed-XML source (for `svg11.document.xml`), root/namespace,
|
|
98
|
+
version, DTD content-model, attribute, CSS grammar, and XML-stylesheet cases;
|
|
99
|
+
- one invalid script, animation, and interaction case.
|
|
100
|
+
|
|
101
|
+
Add `spec/svg_conform/validation/svg_1_1_document_conformance_spec.rb`,
|
|
102
|
+
`spec/svg_conform/validation/css2_core_grammar_spec.rb`,
|
|
103
|
+
`spec/svg_conform/requirements/svg_1_1_document_requirement_spec.rb`,
|
|
104
|
+
`spec/svg_conform/requirements/processing_features_requirement_spec.rb`, and
|
|
105
|
+
`spec/svg_conform/profiles/svg_1_1_full_static_profile_spec.rb`. The profile spec
|
|
106
|
+
runs every fixture through DOM and SAX, compares validity and stable requirement
|
|
107
|
+
IDs, and asserts that all errors have the normative citation. Update
|
|
108
|
+
the existing `docs/profiles.adoc`, `docs/cli_guide.adoc`, and the profile-list
|
|
109
|
+
command coverage with
|
|
110
|
+
the profile ID, scope, citations, non-goals, and example command.
|
|
111
|
+
|
|
112
|
+
## Done when
|
|
113
|
+
|
|
114
|
+
- `svg_1_1_full_static` is discoverable and opt-in; no existing profile or
|
|
115
|
+
default selection changes.
|
|
116
|
+
- All nine matrix rows have a stable ID, normative citation, isolated invalid
|
|
117
|
+
fixture, and matching DOM/SAX result.
|
|
118
|
+
- Valid SVG 1.1 Full fixtures pass local DTD, CSS, and stylesheet checks without
|
|
119
|
+
network access; invalid grammar is rejected by the appropriate requirement.
|
|
120
|
+
- Appendix G.2 foreign content is handled on a validation copy, and an external
|
|
121
|
+
entity attempt cannot read a file or make a network request.
|
|
122
|
+
- Script, animation, and interaction categories are enforced by the serialized
|
|
123
|
+
shared `ProcessingFeaturesRequirement` in both validation modes.
|
|
124
|
+
- Profile documentation states exactly what Full/static covers and does not
|
|
125
|
+
claim Tiny, Basic, rendering, or remediation support.
|
|
126
|
+
- All changed Ruby passes the repository linter and the gem builds.
|
|
127
|
+
|
|
128
|
+
```sh
|
|
129
|
+
bundle exec rspec spec/svg_conform/validation/svg_1_1_document_conformance_spec.rb spec/svg_conform/validation/css2_core_grammar_spec.rb spec/svg_conform/requirements/svg_1_1_document_requirement_spec.rb spec/svg_conform/requirements/processing_features_requirement_spec.rb spec/svg_conform/profiles/svg_1_1_full_static_profile_spec.rb spec/svg_conform/commands/profiles_command_spec.rb
|
|
130
|
+
bundle exec svg_conform check spec/fixtures/profiles/svg_1_1_full_static/valid/minimal-full.svg --profile svg_1_1_full_static --format json
|
|
131
|
+
bundle exec rubocop
|
|
132
|
+
bundle exec rake build
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Status
|
|
136
|
+
|
|
137
|
+
State: done
|
|
138
|
+
PR: https://github.com/claricle/svg_conform/pull/109
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# 04 — Ship SVG 2 secure-static
|
|
2
|
+
|
|
3
|
+
Effort: **4–6 person-days**
|
|
4
|
+
|
|
5
|
+
Repository: `claricle/svg_conform`
|
|
6
|
+
|
|
7
|
+
Depends on: Cards 02 and 03
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Add an opt-in SVG 2 profile for the dated Candidate Recommendation's
|
|
12
|
+
secure-static processing mode. Reuse the shared processing-feature requirement
|
|
13
|
+
and the established reference classifier rather than creating a second URI
|
|
14
|
+
model.
|
|
15
|
+
|
|
16
|
+
## Requirement matrix
|
|
17
|
+
|
|
18
|
+
Add `config/profiles/svg_2_secure_static.yml` with the dated SVG 2 Candidate
|
|
19
|
+
Recommendation as its `specification_uri` and these stable errors:
|
|
20
|
+
|
|
21
|
+
| Requirement ID | Rule | Normative citation |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `svg2.secure_static.script` | Reject script elements and event-handler attributes. | `https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode` |
|
|
24
|
+
| `svg2.secure_static.animation` | Reject SVG/CSS animation and animation-timing features. | `https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode` |
|
|
25
|
+
| `svg2.secure_static.interaction` | Reject interaction-only event and cursor behavior. | `https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode` |
|
|
26
|
+
| `svg2.secure_static.external_reference` | Permit same-document fragment references and supported self-contained data URLs; reject references that require another document, local file, or network resource. | `https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode` |
|
|
27
|
+
|
|
28
|
+
The first three rows configure Card 03's
|
|
29
|
+
`ProcessingFeaturesRequirement`; do not fork the class or its YAML shape for
|
|
30
|
+
SVG 2.
|
|
31
|
+
|
|
32
|
+
## Reference boundary
|
|
33
|
+
|
|
34
|
+
Add `ExternalReferencesRequirement` at
|
|
35
|
+
`lib/svg_conform/requirements/external_references_requirement.rb`. It calls the
|
|
36
|
+
existing public API unchanged:
|
|
37
|
+
|
|
38
|
+
```ruby
|
|
39
|
+
SvgConform::References::ReferenceClassifier.classify(
|
|
40
|
+
href_value,
|
|
41
|
+
element_name:,
|
|
42
|
+
attribute_name:,
|
|
43
|
+
line_number: nil,
|
|
44
|
+
column_number: nil
|
|
45
|
+
)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Keep `InternalFragmentReference`, `DataUriReference`, `UrnReference`,
|
|
49
|
+
`ExternalUrlReference`, and `RelativePathReference` as the returned types, and
|
|
50
|
+
keep `LinkValidationRequirement` on the same classifier. Add behavior to
|
|
51
|
+
`DataUriReference` rather than introducing a second data-URL parser.
|
|
52
|
+
|
|
53
|
+
The requirement inspects:
|
|
54
|
+
|
|
55
|
+
- `href`, `xlink:href`, and SVG URI/IRI-bearing presentation attributes;
|
|
56
|
+
- CSS `url(...)` and `@import` tokens in style attributes and style elements;
|
|
57
|
+
- `xml-stylesheet` processing instructions via Card 03's source hook.
|
|
58
|
+
|
|
59
|
+
Classification is explicit:
|
|
60
|
+
|
|
61
|
+
- `#fragment` in the current document is allowed; the existing link requirement
|
|
62
|
+
still reports a missing fragment target.
|
|
63
|
+
- HTTP(S), protocol-relative URLs, URNs, and relative paths with a resource
|
|
64
|
+
component (including `other.svg#id`) are rejected.
|
|
65
|
+
- A data URL is allowed only when it decodes without external access and its
|
|
66
|
+
media type is `image/png`, `image/jpeg`, or `image/svg+xml`. Raster payloads
|
|
67
|
+
must be non-empty and syntactically decodable; an SVG payload must decode to
|
|
68
|
+
one complete well-formed SVG document. Both base64 and percent-encoded forms
|
|
69
|
+
are covered. Malformed encodings, unsupported media types, and nested external
|
|
70
|
+
references in SVG data URLs are rejected.
|
|
71
|
+
- Empty references and non-resource lexical values retain their existing
|
|
72
|
+
classifier behavior and are not reclassified merely to satisfy this profile.
|
|
73
|
+
|
|
74
|
+
Nested `image/svg+xml` validation applies the external-reference rule with a
|
|
75
|
+
depth limit and cycle guard, but does not recursively run the entire parent
|
|
76
|
+
profile. It reports the outer source location and a JSON-safe nested failure
|
|
77
|
+
reason.
|
|
78
|
+
|
|
79
|
+
## Corpus, tests, and documentation
|
|
80
|
+
|
|
81
|
+
Create `spec/fixtures/profiles/svg_2_secure_static/` with a small, enumerated
|
|
82
|
+
corpus:
|
|
83
|
+
|
|
84
|
+
- valid same-document fragments;
|
|
85
|
+
- valid base64 and percent-encoded PNG/JPEG data URLs;
|
|
86
|
+
- valid base64 and percent-encoded self-contained SVG data URLs;
|
|
87
|
+
- invalid HTTP(S), protocol-relative, relative-file, file-like fragment, URN,
|
|
88
|
+
CSS `url`, CSS `@import`, and XML-stylesheet references;
|
|
89
|
+
- invalid malformed/unsupported data URLs and SVG data URLs with malformed XML,
|
|
90
|
+
nested external content, or excessive nesting;
|
|
91
|
+
- one invalid fixture per script, animation, and interaction row.
|
|
92
|
+
|
|
93
|
+
Extend the existing `spec/svg_conform/references/reference_classifier_spec.rb`,
|
|
94
|
+
`spec/svg_conform/references/integration_spec.rb`, and
|
|
95
|
+
`spec/svg_conform/requirements/link_validation_requirement_spec.rb`. Add
|
|
96
|
+
`spec/svg_conform/references/data_uri_reference_spec.rb`,
|
|
97
|
+
`spec/svg_conform/requirements/external_references_requirement_spec.rb`, and
|
|
98
|
+
`spec/svg_conform/profiles/svg_2_secure_static_profile_spec.rb`. Run the corpus
|
|
99
|
+
through DOM and SAX paths and compare validity, stable IDs, and citations. Update
|
|
100
|
+
the existing `docs/profiles.adoc` and `docs/cli_guide.adoc` with the exact
|
|
101
|
+
accepted-reference table,
|
|
102
|
+
dated citation, profile non-goals, and example command.
|
|
103
|
+
|
|
104
|
+
## Done when
|
|
105
|
+
|
|
106
|
+
- `svg_2_secure_static` is discoverable and opt-in; no existing profile or
|
|
107
|
+
default selection changes.
|
|
108
|
+
- All four matrix rows have stable IDs, the dated secure-static citation,
|
|
109
|
+
isolated invalid fixtures, and matching DOM/SAX reports.
|
|
110
|
+
- Same-document fragments and all six supported data-URL form/media
|
|
111
|
+
combinations pass, while every enumerated external or malformed case fails
|
|
112
|
+
with `svg2.secure_static.external_reference`.
|
|
113
|
+
- `ReferenceClassifier.classify` retains its signature and typed returns;
|
|
114
|
+
existing `LinkValidationRequirement` integration specs continue to pass.
|
|
115
|
+
- Processing-feature behavior comes from the unchanged serialized requirement
|
|
116
|
+
introduced by Card 03.
|
|
117
|
+
- Documentation describes secure-static resource behavior without claiming
|
|
118
|
+
complete SVG 2 document, rendering, or CSS conformance.
|
|
119
|
+
- All changed Ruby passes the repository linter and the gem builds.
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
bundle exec rspec spec/svg_conform/references/reference_classifier_spec.rb spec/svg_conform/references/data_uri_reference_spec.rb spec/svg_conform/references/integration_spec.rb spec/svg_conform/requirements/link_validation_requirement_spec.rb spec/svg_conform/requirements/external_references_requirement_spec.rb spec/svg_conform/requirements/processing_features_requirement_spec.rb spec/svg_conform/profiles/svg_2_secure_static_profile_spec.rb spec/svg_conform/commands/profiles_command_spec.rb
|
|
123
|
+
bundle exec svg_conform check spec/fixtures/profiles/svg_2_secure_static/valid/same-document-fragment.svg --profile svg_2_secure_static --format json
|
|
124
|
+
bundle exec rubocop
|
|
125
|
+
bundle exec rake build
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Status
|
|
129
|
+
|
|
130
|
+
State: done
|
|
131
|
+
PR: https://github.com/claricle/svg_conform/pull/107
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# 05 — Freeze the candidate and adoption handoff
|
|
2
|
+
|
|
3
|
+
Effort: **2–4 person-days**
|
|
4
|
+
|
|
5
|
+
Repositories: `claricle/lens_core`, then `claricle/svg_conform`
|
|
6
|
+
|
|
7
|
+
Depends on: Cards 01–04
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Freeze the v1 candidate against real svg_conform output, pin the round-trip
|
|
12
|
+
corpus, and leave enough format-neutral evidence for another lens to adopt
|
|
13
|
+
LensCore without loading SVG code. The endpoint is ready to tag; gem publication
|
|
14
|
+
and adopter migrations are outside this issue.
|
|
15
|
+
|
|
16
|
+
## Golden corpus
|
|
17
|
+
|
|
18
|
+
In LensCore, add:
|
|
19
|
+
|
|
20
|
+
- `spec/fixtures/v1/golden/svg_conform/svg-1.1-invalid-grammar.json`, exported
|
|
21
|
+
from the Card 03 invalid grammar fixture;
|
|
22
|
+
- `spec/fixtures/v1/golden/svg_conform/svg-2-external-reference.json`, exported
|
|
23
|
+
from the Card 04 external-reference fixture;
|
|
24
|
+
- `spec/fixtures/v1/golden/svg_conform/svg-four-channel-library.json`, exported
|
|
25
|
+
through the public adapter from a focused result containing an error, validity
|
|
26
|
+
error, warning, and info;
|
|
27
|
+
- `spec/fixtures/v1/golden/examples/xml-location.json` and
|
|
28
|
+
`binary-location.json`, format-neutral examples that exercise the two location
|
|
29
|
+
forms without claiming adoption by another lens;
|
|
30
|
+
- `spec/fixtures/v1/golden/manifest.yml`, recording each file's SHA-256,
|
|
31
|
+
producer/version, source fixture, schema version, exact svg_conform commit for
|
|
32
|
+
SVG exports, and the exact pre-freeze LensCore contract commit used to render
|
|
33
|
+
them.
|
|
34
|
+
|
|
35
|
+
All goldens omit timestamps. Add `script/refresh_svg_goldens`, which takes an
|
|
36
|
+
svg_conform checkout path, refuses a checkout whose HEAD does not match the
|
|
37
|
+
manifest's expected commit, invokes the public adapter/renderers, canonicalizes
|
|
38
|
+
through LensCore, and updates only the three SVG JSON files and their hashes.
|
|
39
|
+
The script must not clone, fetch, publish, or write outside LensCore.
|
|
40
|
+
|
|
41
|
+
## Freeze and host-only evidence
|
|
42
|
+
|
|
43
|
+
- Add `spec/lens_core/round_trip_spec.rb` for canonical value and formatting
|
|
44
|
+
round trips, and add `spec/lens_core/golden_corpus_spec.rb` to validate every
|
|
45
|
+
manifest entry against the v1 schema, parse it, render it, and compare bytes
|
|
46
|
+
with the input. Also prove that summary counts equal the diagnostics and that
|
|
47
|
+
profile, citation, context, remediation, and present location fields survive.
|
|
48
|
+
- Add a minimal fixture app at `spec/fixtures/host_app/` whose bundle contains
|
|
49
|
+
only LensCore and Ruby standard libraries. Its check reads the complete golden
|
|
50
|
+
directory, reports profile/count/location information, and never requires
|
|
51
|
+
svg_conform; exercise it from `spec/lens_core/host_only_spec.rb`.
|
|
52
|
+
- Commit the LensCore corpus, checks, and documentation as the immutable freeze
|
|
53
|
+
candidate. Do not try to write that commit's own SHA into a file in the same
|
|
54
|
+
commit.
|
|
55
|
+
- In svg_conform, update the `Gemfile` Git ref and generated `Gemfile.lock` to
|
|
56
|
+
that final LensCore freeze commit. Add `docs/lens_core_handoff.adoc` with the
|
|
57
|
+
exact LensCore freeze commit, schema path and SHA-256, golden manifest path,
|
|
58
|
+
canonical parse/render calls, compatibility/error rules, and the exact
|
|
59
|
+
earlier svg_conform producer commit named by the manifest. Explicitly label
|
|
60
|
+
the binary report as a contract example, not PNG/EMF/PostScript implementation
|
|
61
|
+
evidence.
|
|
62
|
+
- Re-run the Card 02 adapter specs and the two profile specs against that exact
|
|
63
|
+
freeze commit; no API/schema shim may remain only in an uncommitted LensCore
|
|
64
|
+
checkout.
|
|
65
|
+
|
|
66
|
+
If the SVG exports reveal a contract defect, fix schema/model/docs together and
|
|
67
|
+
commit the corrected LensCore contract first. Update svg_conform's temporary pin
|
|
68
|
+
and record a new producer commit, then regenerate all corpus hashes and repeat
|
|
69
|
+
both repositories' focused checks before declaring the later LensCore freeze
|
|
70
|
+
commit immutable.
|
|
71
|
+
|
|
72
|
+
## Done when
|
|
73
|
+
|
|
74
|
+
- The manifest names exact immutable generation commits and SHA-256 values for
|
|
75
|
+
the schema and every golden; the svg_conform lockfile and handoff name the
|
|
76
|
+
later immutable LensCore freeze commit, so no branch-only or working-tree
|
|
77
|
+
dependency remains.
|
|
78
|
+
- Every canonical JSON golden validates and parse/renders byte-for-byte, and the
|
|
79
|
+
four-channel report proves infos and validity errors are retained.
|
|
80
|
+
- The host-only fixture reads XML and binary location examples using LensCore
|
|
81
|
+
alone and has no SVG or other-lens dependency.
|
|
82
|
+
- svg_conform's lockfile resolves the same frozen LensCore commit named by the
|
|
83
|
+
handoff, and focused adapter/SVG 1.1/SVG 2 specs pass at that pin.
|
|
84
|
+
- The handoff clearly separates completed contract/SVG evidence from future
|
|
85
|
+
EMF, PNG, PostScript, release, and publication work.
|
|
86
|
+
- LensCore and svg_conform each pass their changed-Ruby lint and gem build.
|
|
87
|
+
|
|
88
|
+
In `claricle/lens_core`:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
bundle exec rspec spec/lens_core/golden_corpus_spec.rb spec/lens_core/round_trip_spec.rb spec/lens_core/host_only_spec.rb
|
|
92
|
+
bundle exec ruby -Ilib spec/fixtures/host_app/read_reports.rb spec/fixtures/v1/golden
|
|
93
|
+
bundle exec rubocop
|
|
94
|
+
bundle exec rake build
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
In `claricle/svg_conform`:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
bundle exec rspec spec/svg_conform/diagnostics/lens_core_adapter_spec.rb spec/svg_conform/profiles/svg_1_1_full_static_profile_spec.rb spec/svg_conform/profiles/svg_2_secure_static_profile_spec.rb
|
|
101
|
+
bundle exec rubocop
|
|
102
|
+
bundle exec rake build
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Status
|
|
106
|
+
|
|
107
|
+
State: done
|
|
108
|
+
PR: https://github.com/claricle/svg_conform/pull/110
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Issue 100 — Progress and handoff
|
|
2
|
+
|
|
3
|
+
## Current state
|
|
4
|
+
|
|
5
|
+
Planning is complete. Implementation has not started, and every work card is
|
|
6
|
+
`todo` with no PR. The execution order is:
|
|
7
|
+
|
|
8
|
+
| Card | State | Effort | Next dependency |
|
|
9
|
+
| --- | --- | --- | --- |
|
|
10
|
+
| 01 — Build LensCore diagnostics v1 | todo | 4–7 person-days | none |
|
|
11
|
+
| 02 — Adopt LensCore in svg_conform | todo | 3–5 person-days | Card 01 candidate commit |
|
|
12
|
+
| 03 — Ship SVG 1.1 Full/static | todo | 8–12 person-days | Card 02 adapter/citations |
|
|
13
|
+
| 04 — Ship SVG 2 secure-static | todo | 4–6 person-days | Card 02 diagnostics and Card 03 shared plumbing |
|
|
14
|
+
| 05 — Freeze the candidate and adoption handoff | todo | 2–4 person-days | Cards 01–04 complete |
|
|
15
|
+
|
|
16
|
+
Overall: **21–34 person-days**.
|
|
17
|
+
|
|
18
|
+
The next action is Card 01. Card 02 must pin a real candidate commit before SVG
|
|
19
|
+
integration starts; Card 05 replaces that temporary pin with the final frozen
|
|
20
|
+
candidate commit.
|
|
21
|
+
|
|
22
|
+
## Known implementation questions
|
|
23
|
+
|
|
24
|
+
- Card 03 must establish whether the existing Moxml/Leptris stack can perform
|
|
25
|
+
validating, offline SVG 1.1 DTD checks. Its four-probe spike has explicit
|
|
26
|
+
selection criteria and owns any dependency decision; no parser library is
|
|
27
|
+
assumed in advance.
|
|
28
|
+
- SVG 1.1 source-sensitive rules require original declarations, doctypes, and
|
|
29
|
+
processing instructions. Card 03 owns the source hook for both DOM and SAX so
|
|
30
|
+
the implementation does not infer these from an already-normalized tree.
|
|
31
|
+
- The dated SVG 2 source is remote normative material. Card 04 pins citations
|
|
32
|
+
and fixture behavior; it does not copy an untracked local snapshot into the
|
|
33
|
+
profile.
|
|
34
|
+
|
|
35
|
+
## Scope deliberately left out
|
|
36
|
+
|
|
37
|
+
This plan's scope is LensCore, svg_conform adoption, and the two SVG profiles.
|
|
38
|
+
The following are outside it:
|
|
39
|
+
|
|
40
|
+
- **Actual EMF, PNG, and PostScript migrations, dependencies, and report
|
|
41
|
+
goldens.** Those belong to their separate tracker issues. Card 05 supplies the
|
|
42
|
+
exact LensCore commit, schema digest, SVG exports, host-only proof, and generic
|
|
43
|
+
binary-location example they need, without claiming those repositories have
|
|
44
|
+
adopted the contract.
|
|
45
|
+
- **PNG-specific full-report migration, inaccessible-field work, and a
|
|
46
|
+
PNG-only RuboCop command.** No PNG files are in scope, so inventing PNG API or
|
|
47
|
+
fixture requirements here would be unverified cross-repository design.
|
|
48
|
+
- **EMF spec paths that do not exist in the target repository.** The plan does
|
|
49
|
+
not cite or require nonexistent tests; the format-neutral binary example is
|
|
50
|
+
the only evidence needed for this contract issue.
|
|
51
|
+
- **PostScript implementation.** The final scope excludes it entirely, so there
|
|
52
|
+
is no placeholder adapter or speculative field map.
|
|
53
|
+
- **Lens-family release and dependency audit commands.** Publishing LensCore,
|
|
54
|
+
replacing temporary Git pins with a released gem constraint, changing every
|
|
55
|
+
lens gemspec/lockfile, and running their release checks happen after this
|
|
56
|
+
issue. Card 05 ends at an immutable, ready-to-tag candidate and observable
|
|
57
|
+
handoff.
|
|
58
|
+
|
|
59
|
+
## Verification handoff
|
|
60
|
+
|
|
61
|
+
The commands on Cards 01–05 are prospective implementation checks. They are
|
|
62
|
+
focused by design: targeted specs and fixtures, changed-repository RuboCop, and
|
|
63
|
+
gem builds only. No full suite, corpus sweep, or fuzzer is required. Card 05 is
|
|
64
|
+
the final integration gate and must record immutable commits and digests rather
|
|
65
|
+
than branch names.
|
|
@@ -21,7 +21,7 @@ requirements:
|
|
|
21
21
|
element_configs:
|
|
22
22
|
# Direct encoding from svgcheck word_properties.py elements dictionary
|
|
23
23
|
- tag: "svg"
|
|
24
|
-
attributes: ["version", "baseProfile", "width", "viewBox", "preserveAspectRatio", "snapshotTime", "height", "id", "role", "break", "color-rendering", "fill-rule", "overflow", "data-name", "clip-path", "mask"]
|
|
24
|
+
attributes: ["version", "baseProfile", "width", "viewBox", "preserveAspectRatio", "snapshotTime", "height", "id", "role", "break", "color-rendering", "fill-rule", "overflow", "data-name", "clip-path", "mask", "contentStyleType", "zoomAndPan"]
|
|
25
25
|
required_attributes: ["version", "baseProfile"]
|
|
26
26
|
attribute_values:
|
|
27
27
|
version: ["1.2"]
|
|
@@ -61,7 +61,7 @@ requirements:
|
|
|
61
61
|
attributes: ["x", "y", "width", "height", "auto", "id", "role", "fill", "transform", "fill-rule", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "clip-path", "mask"]
|
|
62
62
|
allowed_children: ["desc", "title", "tspan", "text", "a"]
|
|
63
63
|
- tag: "text"
|
|
64
|
-
attributes: ["x", "y", "rotate", "id", "role", "fill", "style", "transform", "font-size", "fill-rule", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "font-stretch", "writing-mode", "text-decoration", "clip-path", "mask"]
|
|
64
|
+
attributes: ["x", "y", "rotate", "id", "role", "fill", "style", "transform", "font-size", "fill-rule", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "font-stretch", "writing-mode", "text-decoration", "clip-path", "mask", "textLength", "lengthAdjust"]
|
|
65
65
|
allowed_children: ["desc", "title", "tspan", "text", "a"]
|
|
66
66
|
- tag: "g"
|
|
67
67
|
attributes: ["label", "class", "id", "role", "fill", "style", "transform", "fill-rule", "visibility", "base", "lang", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "data-name", "clip-path", "mask"]
|
|
@@ -100,7 +100,7 @@ requirements:
|
|
|
100
100
|
attributes: ["x", "y", "href", "xlink:href", "id", "role", "fill", "transform", "fill-rule", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "clip-path", "mask"]
|
|
101
101
|
allowed_children: ["title", "desc"]
|
|
102
102
|
- tag: "a"
|
|
103
|
-
attributes: ["id", "role", "fill", "transform", "fill-rule", "target", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space"]
|
|
103
|
+
attributes: ["id", "role", "fill", "transform", "fill-rule", "target", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "title"]
|
|
104
104
|
allowed_children: ["title", "path", "rect", "circle", "line", "ellipse", "polyline", "polygon", "solidColor", "textArea", "text", "g", "defs", "use", "a", "tspan", "desc"]
|
|
105
105
|
- tag: "tspan"
|
|
106
106
|
attributes: ["x", "y", "id", "role", "fill", "fill-rule", "base", "lang", "class", "rel", "rev", "typeof", "content", "datatype", "resource", "about", "property", "space", "letter-spacing"]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: "svg_1_1_full_static"
|
|
2
|
+
description: "SVG 1.1 Full (Second Edition) document grammar under static processing"
|
|
3
|
+
specification_uri: "https://www.w3.org/TR/2011/REC-SVG11-20110816/"
|
|
4
|
+
specification_label: "Scalable Vector Graphics (SVG) 1.1 (Second Edition)"
|
|
5
|
+
|
|
6
|
+
requirements:
|
|
7
|
+
- id: "svg11.document.xml"
|
|
8
|
+
type: "Svg11DocumentRequirement"
|
|
9
|
+
rule: "xml"
|
|
10
|
+
description: "The source is well-formed XML and exposes its original declaration, doctype, and processing instructions"
|
|
11
|
+
citation_uri: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGDocuments"
|
|
12
|
+
citation_label: "Conforming SVG Documents"
|
|
13
|
+
- id: "svg11.document.root"
|
|
14
|
+
type: "Svg11DocumentRequirement"
|
|
15
|
+
rule: "root"
|
|
16
|
+
description: "The document element is svg in the SVG namespace"
|
|
17
|
+
citation_uri: "https://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#SVGElement"
|
|
18
|
+
citation_label: "The svg element"
|
|
19
|
+
- id: "svg11.document.version"
|
|
20
|
+
type: "Svg11DocumentRequirement"
|
|
21
|
+
rule: "version"
|
|
22
|
+
description: "The root declares SVG version 1.1"
|
|
23
|
+
citation_uri: "https://www.w3.org/TR/2011/REC-SVG11-20110816/struct.html#SVGElementVersionAttribute"
|
|
24
|
+
citation_label: "The version attribute"
|
|
25
|
+
- id: "svg11.document.grammar"
|
|
26
|
+
type: "Svg11DocumentRequirement"
|
|
27
|
+
rule: "grammar"
|
|
28
|
+
description: "Elements, attributes and content models validate against the pinned SVG 1.1 Full flat DTD after the Appendix G.2 foreign-namespace transform"
|
|
29
|
+
citation_uri: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGDocuments"
|
|
30
|
+
citation_label: "Conforming SVG Documents"
|
|
31
|
+
- id: "svg11.document.css2"
|
|
32
|
+
type: "Svg11DocumentRequirement"
|
|
33
|
+
rule: "css2"
|
|
34
|
+
description: "Style attributes and style sheets conform to the CSS 2 core grammar (syntax only)"
|
|
35
|
+
citation_uri: "https://www.w3.org/TR/2008/REC-CSS2-20080411/grammar.html"
|
|
36
|
+
citation_label: "CSS 2 grammar"
|
|
37
|
+
- id: "svg11.document.xml_stylesheet"
|
|
38
|
+
type: "Svg11DocumentRequirement"
|
|
39
|
+
rule: "xml_stylesheet"
|
|
40
|
+
description: "xml-stylesheet processing instructions obey their pseudo-attribute syntax and SVG applicability"
|
|
41
|
+
citation_uri: "https://www.w3.org/TR/1999/REC-xml-stylesheet-19990629/"
|
|
42
|
+
citation_label: "Associating Style Sheets with XML documents"
|
|
43
|
+
- id: "svg11.processing"
|
|
44
|
+
type: "ProcessingFeaturesRequirement"
|
|
45
|
+
description: "Static processing rejects script, animation and interaction"
|
|
46
|
+
categories:
|
|
47
|
+
- name: "script"
|
|
48
|
+
id: "svg11.processing.script"
|
|
49
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
50
|
+
description: "Static mode rejects script elements and event-handler attributes"
|
|
51
|
+
elements: ["script"]
|
|
52
|
+
attributes:
|
|
53
|
+
[onabort, onerror, onload, onresize, onscroll, onunload, onzoom]
|
|
54
|
+
- name: "animation"
|
|
55
|
+
id: "svg11.processing.animation"
|
|
56
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
57
|
+
description: "Static mode rejects animation elements and animation-timing attributes"
|
|
58
|
+
elements: [animate, animateColor, animateMotion, animateTransform, set, mpath]
|
|
59
|
+
attributes:
|
|
60
|
+
[begin, end, dur, min, max, restart, repeatCount, repeatDur, calcMode,
|
|
61
|
+
keyTimes, keySplines, onbegin, onend, onrepeat]
|
|
62
|
+
- name: "interaction"
|
|
63
|
+
id: "svg11.processing.interaction"
|
|
64
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
65
|
+
description: "Static mode rejects interaction-only event attributes and cursor behavior"
|
|
66
|
+
elements: ["cursor"]
|
|
67
|
+
attributes:
|
|
68
|
+
[onactivate, onclick, onfocusin, onfocusout, onmousedown, onmousemove,
|
|
69
|
+
onmouseout, onmouseover, onmouseup, cursor]
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: "svg_2_secure_static"
|
|
2
|
+
description: "Opt-in SVG 2 secure-static processing mode: no script, animation, interaction or external resources"
|
|
3
|
+
specification_uri: "https://www.w3.org/TR/2026/CR-SVG2-20261006/"
|
|
4
|
+
specification_label: "Scalable Vector Graphics (SVG) 2, Candidate Recommendation 6 October 2026"
|
|
5
|
+
|
|
6
|
+
# Scope: secure-static resource behavior only. This is not a complete SVG 2
|
|
7
|
+
# document, rendering or CSS conformance check.
|
|
8
|
+
requirements:
|
|
9
|
+
# Same shape as config/requirements/processing_features_static.yml;
|
|
10
|
+
# only ids, citations and the feature lists differ.
|
|
11
|
+
- id: "svg2.secure_static.processing"
|
|
12
|
+
type: "ProcessingFeaturesRequirement"
|
|
13
|
+
description: "Secure-static mode rejects script, animation and interaction"
|
|
14
|
+
categories:
|
|
15
|
+
- name: "script"
|
|
16
|
+
id: "svg2.secure_static.script"
|
|
17
|
+
citation: "https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode"
|
|
18
|
+
description: "Secure-static mode rejects script elements and event-handler attributes"
|
|
19
|
+
elements: ["script"]
|
|
20
|
+
attributes:
|
|
21
|
+
[onabort, onerror, onload, onresize, onscroll, onunload, onzoom]
|
|
22
|
+
- name: "animation"
|
|
23
|
+
id: "svg2.secure_static.animation"
|
|
24
|
+
citation: "https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode"
|
|
25
|
+
description: "Secure-static mode rejects SVG/CSS animation and animation-timing features"
|
|
26
|
+
elements: [animate, animateColor, animateMotion, animateTransform, set, mpath, discard]
|
|
27
|
+
attributes:
|
|
28
|
+
[begin, end, dur, min, max, restart, repeatCount, repeatDur, calcMode,
|
|
29
|
+
keyTimes, keySplines, onbegin, onend, onrepeat]
|
|
30
|
+
attribute_patterns:
|
|
31
|
+
- "\\Aanimation(-.+)?\\z"
|
|
32
|
+
- "\\Atransition(-.+)?\\z"
|
|
33
|
+
- name: "interaction"
|
|
34
|
+
id: "svg2.secure_static.interaction"
|
|
35
|
+
citation: "https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode"
|
|
36
|
+
description: "Secure-static mode rejects interaction-only event attributes and cursor behavior"
|
|
37
|
+
elements: ["cursor"]
|
|
38
|
+
attributes:
|
|
39
|
+
[onactivate, onauxclick, onblur, onclick, ondblclick, onfocus,
|
|
40
|
+
onfocusin, onfocusout, onkeydown, onkeypress, onkeyup, onmousedown,
|
|
41
|
+
onmouseenter, onmouseleave, onmousemove, onmouseout, onmouseover,
|
|
42
|
+
onmouseup, onwheel, ontouchstart, ontouchend, ontouchmove,
|
|
43
|
+
ontouchcancel, cursor]
|
|
44
|
+
# Every other event-handler attribute (onpointerdown, ondragstart, ...).
|
|
45
|
+
# An attribute is reported by the first category that lists it, so the
|
|
46
|
+
# named script and animation handlers above keep their own ids.
|
|
47
|
+
attribute_patterns:
|
|
48
|
+
- "\\Aon.+\\z"
|
|
49
|
+
|
|
50
|
+
- id: "svg2.secure_static.external_reference"
|
|
51
|
+
type: "ExternalReferencesRequirement"
|
|
52
|
+
description: "Permits same-document fragments and self-contained image data URLs; rejects references to another document, local file or network resource"
|
|
53
|
+
citation_uri: "https://www.w3.org/TR/2026/CR-SVG2-20261006/conform.html#secure-static-mode"
|
|
54
|
+
citation_label: "SVG 2 CR, secure static mode"
|
|
55
|
+
max_data_uri_depth: 3
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Static-processing categories for ProcessingFeaturesRequirement.
|
|
2
|
+
# Profiles copy this requirement entry into their `requirements` list.
|
|
3
|
+
id: "svg11.processing"
|
|
4
|
+
type: "ProcessingFeaturesRequirement"
|
|
5
|
+
description: "Static processing rejects script, animation and interaction"
|
|
6
|
+
categories:
|
|
7
|
+
- name: "script"
|
|
8
|
+
id: "svg11.processing.script"
|
|
9
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
10
|
+
description: "Static mode rejects script elements and event-handler attributes"
|
|
11
|
+
elements: ["script"]
|
|
12
|
+
attributes:
|
|
13
|
+
[onabort, onerror, onload, onresize, onscroll, onunload, onzoom]
|
|
14
|
+
- name: "animation"
|
|
15
|
+
id: "svg11.processing.animation"
|
|
16
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
17
|
+
description: "Static mode rejects animation elements and animation-timing attributes"
|
|
18
|
+
elements: [animate, animateColor, animateMotion, animateTransform, set, mpath]
|
|
19
|
+
attributes:
|
|
20
|
+
[begin, end, dur, min, max, restart, repeatCount, repeatDur, calcMode,
|
|
21
|
+
keyTimes, keySplines, onbegin, onend, onrepeat]
|
|
22
|
+
- name: "interaction"
|
|
23
|
+
id: "svg11.processing.interaction"
|
|
24
|
+
citation: "https://www.w3.org/TR/2011/REC-SVG11-20110816/conform.html#ConformingSVGViewers"
|
|
25
|
+
description: "Static mode rejects interaction-only event attributes and cursor behavior"
|
|
26
|
+
elements: ["cursor"]
|
|
27
|
+
attributes:
|
|
28
|
+
[onactivate, onclick, onfocusin, onfocusout, onmousedown, onmousemove,
|
|
29
|
+
onmouseout, onmouseover, onmouseup, cursor]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Vendored SVG 1.1 (Second Edition, 16 August 2011) flat DTD.
|
|
2
|
+
# Validation resolves this file locally; no network or external entity access.
|
|
3
|
+
files:
|
|
4
|
+
- path: svg11-flat-20110816.dtd
|
|
5
|
+
source_url: https://www.w3.org/Graphics/SVG/1.1/DTD/svg11-flat-20110816.dtd
|
|
6
|
+
retrieved: 2026-10-23
|
|
7
|
+
sha256: 7c22266d65655a7d359e9e79a107d156e64b29a87491313be2092bd66cab3b9b
|