File: doctype.rs

package info (click to toggle)
rust-xmlparser 0.13.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 252 kB
  • sloc: makefile: 4
file content (172 lines) | stat: -rw-r--r-- 5,248 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
use crate::token::*;

test!(dtd_01, "<!DOCTYPE greeting SYSTEM \"hello.dtd\">",
    Token::EmptyDtd("greeting", Some(ExternalId::System("hello.dtd")), 0..38)
);

test!(dtd_02, "<!DOCTYPE greeting PUBLIC \"hello.dtd\" \"goodbye.dtd\">",
    Token::EmptyDtd("greeting", Some(ExternalId::Public("hello.dtd", "goodbye.dtd")), 0..52)
);

test!(dtd_03, "<!DOCTYPE greeting SYSTEM 'hello.dtd'>",
    Token::EmptyDtd("greeting", Some(ExternalId::System("hello.dtd")), 0..38)
);

test!(dtd_04, "<!DOCTYPE greeting>",
    Token::EmptyDtd("greeting", None, 0..19)
);

test!(dtd_05, "<!DOCTYPE greeting []>",
    Token::DtdStart("greeting", None, 0..20),
    Token::DtdEnd(20..22)
);

test!(dtd_06, "<!DOCTYPE greeting><a/>",
    Token::EmptyDtd("greeting", None, 0..19),
    Token::ElementStart("", "a", 19..21),
    Token::ElementEnd(ElementEnd::Empty, 21..23)
);

test!(dtd_07, "<!DOCTYPE greeting [] >",
    Token::DtdStart("greeting", None, 0..20),
    Token::DtdEnd(20..23)
);

test!(dtd_08, "<!DOCTYPE greeting [ ] >",
    Token::DtdStart("greeting", None, 0..20),
    Token::DtdEnd(21..24)
);

test!(dtd_entity_01,
"<!DOCTYPE svg [
    <!ENTITY ns_extend \"http://ns.adobe.com/Extensibility/1.0/\">
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "ns_extend",
        EntityDefinition::EntityValue("http://ns.adobe.com/Extensibility/1.0/"),
        20..80,
    ),
    Token::DtdEnd(81..83)
);

test!(dtd_entity_02,
"<!DOCTYPE svg [
    <!ENTITY Pub-Status \"This is a pre-release of the
specification.\">
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "Pub-Status",
        EntityDefinition::EntityValue("This is a pre-release of the\nspecification."),
        20..86,
    ),
    Token::DtdEnd(87..89)
);

test!(dtd_entity_03,
"<!DOCTYPE svg [
    <!ENTITY open-hatch SYSTEM \"http://www.textuality.com/boilerplate/OpenHatch.xml\">
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "open-hatch",
        EntityDefinition::ExternalId(ExternalId::System("http://www.textuality.com/boilerplate/OpenHatch.xml")),
        20..101,
    ),
    Token::DtdEnd(102..104)
);

test!(dtd_entity_04,
"<!DOCTYPE svg [
    <!ENTITY open-hatch
             PUBLIC \"-//Textuality//TEXT Standard open-hatch boilerplate//EN\"
             \"http://www.textuality.com/boilerplate/OpenHatch.xml\">
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "open-hatch",
        EntityDefinition::ExternalId(
            ExternalId::Public(
                "-//Textuality//TEXT Standard open-hatch boilerplate//EN",
                "http://www.textuality.com/boilerplate/OpenHatch.xml"
            )
        ),
        20..185,
    ),
    Token::DtdEnd(186..188)
);

// TODO: NDATA will be ignored
test!(dtd_entity_05,
"<!DOCTYPE svg [
    <!ENTITY hatch-pic SYSTEM \"../grafix/OpenHatch.gif\" NDATA gif >
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "hatch-pic",
        EntityDefinition::ExternalId(ExternalId::System("../grafix/OpenHatch.gif")),
        20..83,
    ),
    Token::DtdEnd(84..86)
);

// TODO: unsupported data will be ignored
test!(dtd_entity_06,
"<!DOCTYPE svg [
    <!ELEMENT sgml ANY>
    <!ENTITY ns_extend \"http://ns.adobe.com/Extensibility/1.0/\">
    <!NOTATION example1SVG-rdf SYSTEM \"example1.svg.rdf\">
    <!ATTLIST img data ENTITY #IMPLIED>
]>",
    Token::DtdStart("svg", None, 0..15),
    Token::EntityDecl(
        "ns_extend",
        EntityDefinition::EntityValue("http://ns.adobe.com/Extensibility/1.0/"),
        44..104
    ),
    Token::DtdEnd(203..205)
);

// We do not support !ELEMENT DTD token and it will be skipped.
// Previously, we were calling `Tokenizer::next` after the skip,
// which is recursive and could cause a stack overflow when there are too many sequential
// unsupported tokens.
// This tests checks that the current code do not crash with stack overflow.
#[test]
fn dtd_entity_07() {
    let mut text = "<!DOCTYPE svg [\n".to_string();
    for _ in 0..500 {
        text.push_str("<!ELEMENT sgml ANY>\n");
    }
    text.push_str("]>\n");

    let mut p = xml::Tokenizer::from(text.as_str());
    assert_eq!(to_test_token(p.next().unwrap()), Token::DtdStart("svg", None, 0..15));
    assert_eq!(to_test_token(p.next().unwrap()), Token::DtdEnd(10016..10018));
}

test!(dtd_err_01, "<!DOCTYPEEG[<!ENTITY%ETT\u{000a}SSSSSSSS<D_IDYT;->\u{000a}<",
    Token::Error("invalid DTD at 1:1 cause expected space not 'E' at 1:10".to_string())
);

test!(dtd_err_02, "<!DOCTYPE s [<!ENTITY % name S YSTEM",
    Token::DtdStart("s", None, 0..13),
    Token::Error("invalid DTD entity at 1:14 cause invalid ExternalID".to_string())
);

test!(dtd_err_03, "<!DOCTYPE s [<!ENTITY % name B",
    Token::DtdStart("s", None, 0..13),
    Token::Error("invalid DTD entity at 1:14 cause \
                  expected '\"', ''', 'S', 'P' not 'B' at 1:30".to_string())
);

test!(dtd_err_04, "<!DOCTYPE s []",
    Token::DtdStart("s", None, 0..13),
    Token::Error("invalid DTD at 1:14 cause unexpected end of stream".to_string())
);

test!(dtd_err_05, "<!DOCTYPE s [] !",
    Token::DtdStart("s", None, 0..13),
    Token::Error("invalid DTD at 1:14 cause expected '>' not '!' at 1:16".to_string())
);