Line data Source code
1 : /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifdef IS_LITTLE_ENDIAN
7 :
8 : #define PREFIX(ident) little2_ ## ident
9 : #define BYTE_TYPE(p) LITTLE2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
10 : #define IS_NAME_CHAR_MINBPC(p) LITTLE2_IS_NAME_CHAR_MINBPC(0, p)
11 : #define IS_NMSTRT_CHAR_MINBPC(p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(0, p)
12 :
13 : #else
14 :
15 : #define PREFIX(ident) big2_ ## ident
16 : #define BYTE_TYPE(p) BIG2_BYTE_TYPE(XmlGetUtf16InternalEncodingNS(), p)
17 : #define IS_NAME_CHAR_MINBPC(p) BIG2_IS_NAME_CHAR_MINBPC(0, p)
18 : #define IS_NMSTRT_CHAR_MINBPC(p) BIG2_IS_NMSTRT_CHAR_MINBPC(0, p)
19 :
20 : #endif
21 :
22 : #define MOZ_EXPAT_VALID_QNAME (0)
23 : #define MOZ_EXPAT_EMPTY_QNAME (1 << 0)
24 : #define MOZ_EXPAT_INVALID_CHARACTER (1 << 1)
25 : #define MOZ_EXPAT_MALFORMED (1 << 2)
26 :
27 672 : int MOZ_XMLCheckQName(const char* ptr, const char* end, int ns_aware,
28 : const char** colon)
29 : {
30 672 : int result = MOZ_EXPAT_VALID_QNAME;
31 672 : int nmstrt = 1;
32 672 : *colon = 0;
33 672 : if (ptr == end) {
34 0 : return MOZ_EXPAT_EMPTY_QNAME;
35 : }
36 : do {
37 5022 : switch (BYTE_TYPE(ptr)) {
38 : case BT_COLON:
39 : /* We're namespace-aware and either first or last character is a colon
40 : or we've already seen a colon. */
41 0 : if (ns_aware && (nmstrt || *colon || ptr + 2 == end)) {
42 0 : return MOZ_EXPAT_MALFORMED;
43 : }
44 0 : *colon = ptr;
45 0 : nmstrt = ns_aware; /* e.g. "a:0" should be valid if !ns_aware */
46 0 : break;
47 : case BT_NONASCII:
48 0 : if (!IS_NAME_CHAR_MINBPC(ptr) ||
49 0 : (nmstrt && !*colon && !IS_NMSTRT_CHAR_MINBPC(ptr))) {
50 0 : return MOZ_EXPAT_INVALID_CHARACTER;
51 : }
52 0 : if (nmstrt && *colon && !IS_NMSTRT_CHAR_MINBPC(ptr)) {
53 : /* If a non-starting character like a number is right after the colon,
54 : this is a namespace error, not invalid character */
55 0 : return MOZ_EXPAT_MALFORMED;
56 : }
57 0 : nmstrt = 0;
58 0 : break;
59 : case BT_NMSTRT:
60 : case BT_HEX:
61 5007 : nmstrt = 0;
62 5007 : break;
63 : case BT_DIGIT:
64 : case BT_NAME:
65 : case BT_MINUS:
66 15 : if (nmstrt) {
67 0 : return MOZ_EXPAT_INVALID_CHARACTER;
68 : }
69 15 : break;
70 : default:
71 0 : return MOZ_EXPAT_INVALID_CHARACTER;
72 : }
73 5022 : ptr += 2;
74 5022 : } while (ptr != end);
75 672 : return result;
76 : }
77 :
78 0 : int MOZ_XMLIsLetter(const char* ptr)
79 : {
80 0 : switch (BYTE_TYPE(ptr)) {
81 : case BT_NONASCII:
82 0 : if (!IS_NMSTRT_CHAR_MINBPC(ptr)) {
83 0 : return 0;
84 : }
85 : /* fall through */
86 : case BT_NMSTRT:
87 : case BT_HEX:
88 0 : return 1;
89 : default:
90 0 : return 0;
91 : }
92 : }
93 :
94 0 : int MOZ_XMLIsNCNameChar(const char* ptr)
95 : {
96 0 : switch (BYTE_TYPE(ptr)) {
97 : case BT_NONASCII:
98 0 : if (!IS_NAME_CHAR_MINBPC(ptr)) {
99 0 : return 0;
100 : }
101 : /* fall through */
102 : case BT_NMSTRT:
103 : case BT_HEX:
104 : case BT_DIGIT:
105 : case BT_NAME:
106 : case BT_MINUS:
107 0 : return 1;
108 : default:
109 0 : return 0;
110 : }
111 : }
112 :
113 0 : int MOZ_XMLTranslateEntity(const char* ptr, const char* end, const char** next,
114 : XML_Char* result)
115 : {
116 : // Can we assert here somehow?
117 : // MOZ_ASSERT(*ptr == '&');
118 :
119 0 : const ENCODING* enc = XmlGetUtf16InternalEncodingNS();
120 : /* scanRef expects to be pointed to the char after the '&'. */
121 0 : int tok = PREFIX(scanRef)(enc, ptr + enc->minBytesPerChar, end, next);
122 0 : if (tok <= XML_TOK_INVALID) {
123 0 : return 0;
124 : }
125 :
126 0 : if (tok == XML_TOK_CHAR_REF) {
127 : /* XmlCharRefNumber expects to be pointed to the '&'. */
128 0 : int n = XmlCharRefNumber(enc, ptr);
129 :
130 : /* We could get away with just < 0, but better safe than sorry. */
131 0 : if (n <= 0) {
132 0 : return 0;
133 : }
134 :
135 0 : return XmlUtf16Encode(n, (unsigned short*)result);
136 : }
137 :
138 0 : if (tok == XML_TOK_ENTITY_REF) {
139 : /* XmlPredefinedEntityName expects to be pointed to the char after '&'.
140 :
141 : *next points to after the semicolon, so the entity ends at
142 : *next - enc->minBytesPerChar. */
143 0 : XML_Char ch =
144 0 : (XML_Char)XmlPredefinedEntityName(enc, ptr + enc->minBytesPerChar,
145 : *next - enc->minBytesPerChar);
146 0 : if (!ch) {
147 0 : return 0;
148 : }
149 :
150 0 : *result = ch;
151 0 : return 1;
152 : }
153 :
154 0 : return 0;
155 : }
156 :
157 : #undef PREFIX
158 : #undef BYTE_TYPE
159 : #undef IS_NAME_CHAR_MINBPC
160 : #undef IS_NMSTRT_CHAR_MINBPC
|