@@ -52,6 +52,8 @@ static AttrCheck CheckType;
52
52
static AttrCheck CheckRDFaSafeCURIE ;
53
53
static AttrCheck CheckRDFaTerm ;
54
54
static AttrCheck CheckRDFaPrefix ;
55
+ static AttrCheck CheckDecimal ;
56
+ static AttrCheck CheckSvgAttr ;
55
57
56
58
#define CH_PCDATA NULL
57
59
#define CH_CHARSET NULL
@@ -97,6 +99,8 @@ static AttrCheck CheckRDFaPrefix;
97
99
#define CH_RDFASCURIES CheckRDFaSafeCURIE
98
100
#define CH_RDFATERM CheckRDFaTerm
99
101
#define CH_RDFATERMS CheckRDFaTerm
102
+ #define CH_DECIMAL CheckDecimal
103
+ #define CH_SVG CheckSvgAttr
100
104
101
105
static const Attribute attribute_defs [] =
102
106
{
@@ -444,6 +448,22 @@ static const Attribute attribute_defs [] =
444
448
/* for xmlns:xlink in <svg> */
445
449
{ TidyAttr_XMLNSXLINK , "xmlns:xlink" , CH_URL },
446
450
451
+ /* SVG paint attributes (SVG 1.1) */
452
+ { TidyAttr_FILL , "fill" , CH_SVG },
453
+ { TidyAttr_FILLRULE , "fill-rule" , CH_SVG },
454
+ { TidyAttr_STROKE , "stroke" , CH_SVG },
455
+ { TidyAttr_STROKEDASHARRAY , "stroke-dasharray" , CH_SVG },
456
+ { TidyAttr_STROKEDASHOFFSET , "stroke-dashoffset" , CH_SVG },
457
+ { TidyAttr_STROKELINECAP , "stroke-linecap" , CH_SVG },
458
+ { TidyAttr_STROKELINEJOIN , "stroke-linejoin" , CH_SVG },
459
+ { TidyAttr_STROKEMITERLIMIT , "stroke-miterlimit" , CH_SVG },
460
+ { TidyAttr_STROKEWIDTH , "stroke-width" , CH_SVG },
461
+ { TidyAttr_COLORINTERPOLATION , "color-interpolation" , CH_SVG },
462
+ { TidyAttr_COLORRENDERING , "color-rendering" , CH_SVG },
463
+ { TidyAttr_OPACITY , "opacity" , CH_SVG },
464
+ { TidyAttr_STROKEOPACITY , "stroke-opacity" , CH_SVG },
465
+ { TidyAttr_FILLOPACITY , "fill-opacity" , CH_SVG },
466
+
447
467
/* this must be the final entry */
448
468
{ N_TIDY_ATTRIBS , NULL , NULL }
449
469
};
@@ -2099,6 +2119,180 @@ void CheckType( TidyDocImpl* doc, Node *node, AttVal *attval)
2099
2119
return ;
2100
2120
}
2101
2121
2122
+ static void CheckDecimal ( TidyDocImpl * doc , Node * node , AttVal * attval )
2123
+ {
2124
+ tmbstr p ;
2125
+ Bool hasPoint = no ;
2126
+
2127
+ p = attval -> value ;
2128
+
2129
+ /* Allow leading sign */
2130
+ if (* p == '+' || * p == '-' )
2131
+ ++ p ;
2132
+
2133
+ while (* p )
2134
+ {
2135
+ /* Allow a single decimal point */
2136
+ if (* p == '.' )
2137
+ {
2138
+ if (!hasPoint )
2139
+ hasPoint = yes ;
2140
+ else
2141
+ TY_ (ReportAttrError )( doc , node , attval , BAD_ATTRIBUTE_VALUE );
2142
+ break ;
2143
+ }
2144
+
2145
+ if (!TY_ (IsDigit )(* p ))
2146
+ {
2147
+ TY_ (ReportAttrError )( doc , node , attval , BAD_ATTRIBUTE_VALUE );
2148
+ break ;
2149
+ }
2150
+ ++ p ;
2151
+ }
2152
+ }
2153
+
2154
+ static Bool IsSvgPaintAttr (AttVal * attval )
2155
+ {
2156
+ return attrIsCOLOR (attval )
2157
+ || attrIsSVG_FILL (attval )
2158
+ || attrIsSVG_FILLRULE (attval )
2159
+ || attrIsSVG_STROKE (attval )
2160
+ || attrIsSVG_STROKEDASHARRAY (attval )
2161
+ || attrIsSVG_STROKEDASHOFFSET (attval )
2162
+ || attrIsSVG_STROKELINECAP (attval )
2163
+ || attrIsSVG_STROKELINEJOIN (attval )
2164
+ || attrIsSVG_STROKEMITERLIMIT (attval )
2165
+ || attrIsSVG_STROKEWIDTH (attval )
2166
+ || attrIsSVG_COLORINTERPOLATION (attval )
2167
+ || attrIsSVG_COLORRENDERING (attval )
2168
+ || attrIsSVG_OPACITY (attval )
2169
+ || attrIsSVG_STROKEOPACITY (attval )
2170
+ || attrIsSVG_FILLOPACITY (attval );
2171
+ }
2172
+
2173
+ /* Check SVG attributes */
2174
+ static void CheckSvgAttr ( TidyDocImpl * doc , Node * node , AttVal * attval )
2175
+ {
2176
+ if (!nodeIsSVG (node ))
2177
+ {
2178
+ TY_ (ReportAttrError )(doc , node , attval , ATTRIBUTE_IS_NOT_ALLOWED );
2179
+ return ;
2180
+ }
2181
+
2182
+ /* Issue #903 - check SVG paint attributes */
2183
+ if (IsSvgPaintAttr (attval ))
2184
+ {
2185
+ /* all valid paint attributes have values */
2186
+ if (!AttrHasValue (attval ))
2187
+ {
2188
+ TY_ (ReportAttrError )(doc , node , attval , MISSING_ATTR_VALUE );
2189
+ return ;
2190
+ }
2191
+ /* all paint attributes support an 'inherit' value,
2192
+ per https://dev.w3.org/SVG/profiles/1.1F2/publish/painting.html#SpecifyingPaint */
2193
+ if (AttrValueIs (attval , "inherit" ))
2194
+ {
2195
+ return ;
2196
+ }
2197
+
2198
+ /* check paint datatypes
2199
+ see https://dev.w3.org/SVG/profiles/1.1F2/publish/painting.html#SpecifyingPaint
2200
+ */
2201
+ if (attrIsSVG_FILL (attval ) || attrIsSVG_STROKE (attval ))
2202
+ {
2203
+ /* TODO: support funciri */
2204
+ static ctmbstr const values [] = {
2205
+ "none" , "currentColor" , NULL };
2206
+
2207
+ if (AttrValueIsAmong (attval , values ))
2208
+ CheckLowerCaseAttrValue (doc , node , attval );
2209
+ else
2210
+ CheckColor (doc , node , attval );
2211
+ }
2212
+ else if (attrIsSVG_FILLRULE (attval ))
2213
+ {
2214
+ static ctmbstr const values [] = {"nonzero" , "evenodd" , NULL };
2215
+
2216
+ if (AttrValueIsAmong (attval , values ))
2217
+ CheckLowerCaseAttrValue (doc , node , attval );
2218
+ else
2219
+ TY_ (ReportAttrError )(doc , node , attval , BAD_ATTRIBUTE_VALUE );
2220
+ }
2221
+ else if (attrIsSVG_STROKEDASHARRAY (attval ))
2222
+ {
2223
+ static ctmbstr const values [] = {"none" , NULL };
2224
+
2225
+ if (AttrValueIsAmong (attval , values ))
2226
+ CheckLowerCaseAttrValue (doc , node , attval );
2227
+ else
2228
+ {
2229
+ /* TODO: process dash arrays */
2230
+ }
2231
+ }
2232
+ else if (attrIsSVG_STROKEDASHOFFSET (attval ))
2233
+ {
2234
+ CheckLength (doc , node , attval );
2235
+ }
2236
+ else if (attrIsSVG_STROKELINECAP (attval ))
2237
+ {
2238
+ static ctmbstr const values [] = {"butt" , "round" , "square" , NULL };
2239
+
2240
+ if (AttrValueIsAmong (attval , values ))
2241
+ CheckLowerCaseAttrValue (doc , node , attval );
2242
+ else
2243
+ TY_ (ReportAttrError )(doc , node , attval , BAD_ATTRIBUTE_VALUE );
2244
+ }
2245
+ else if (attrIsSVG_STROKELINEJOIN (attval ))
2246
+ {
2247
+ static ctmbstr const values [] = {"miter" , "round" , "bevel" , NULL };
2248
+
2249
+ if (AttrValueIsAmong (attval , values ))
2250
+ CheckLowerCaseAttrValue (doc , node , attval );
2251
+ else
2252
+ TY_ (ReportAttrError )(doc , node , attval , BAD_ATTRIBUTE_VALUE );
2253
+ }
2254
+ else if (attrIsSVG_STROKEMITERLIMIT (attval ))
2255
+ {
2256
+ CheckNumber (doc , node , attval );
2257
+ }
2258
+ else if (attrIsSVG_STROKEWIDTH (attval ))
2259
+ {
2260
+ CheckLength (doc , node , attval );
2261
+ }
2262
+ else if (attrIsSVG_COLORINTERPOLATION (attval ))
2263
+ {
2264
+ static ctmbstr const values [] = {"auto" , "sRGB" , "linearRGB" , NULL };
2265
+
2266
+ if (AttrValueIsAmong (attval , values ))
2267
+ CheckLowerCaseAttrValue (doc , node , attval );
2268
+ else
2269
+ TY_ (ReportAttrError )(doc , node , attval , BAD_ATTRIBUTE_VALUE );
2270
+ }
2271
+ else if (attrIsSVG_COLORRENDERING (attval ))
2272
+ {
2273
+ static ctmbstr const values [] = {
2274
+ "auto" , "optimizeSpeed" , "optimizeQuality" , NULL };
2275
+
2276
+ if (AttrValueIsAmong (attval , values ))
2277
+ CheckLowerCaseAttrValue (doc , node , attval );
2278
+ else
2279
+ TY_ (ReportAttrError )(doc , node , attval , BAD_ATTRIBUTE_VALUE );
2280
+ }
2281
+ else if (attrIsSVG_OPACITY (attval ))
2282
+ {
2283
+ CheckDecimal (doc , node , attval );
2284
+ }
2285
+ else if (attrIsSVG_STROKEOPACITY (attval ))
2286
+ {
2287
+ CheckDecimal (doc , node , attval );
2288
+ }
2289
+ else if (attrIsSVG_FILLOPACITY (attval ))
2290
+ {
2291
+ CheckDecimal (doc , node , attval );
2292
+ }
2293
+ }
2294
+ }
2295
+
2102
2296
static
2103
2297
AttVal * SortAttVal ( TidyDocImpl * doc , AttVal * list , TidyAttrSortStrategy strat );
2104
2298
0 commit comments