Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(576)

Side by Side Diff: Source/core/svg/SVGParserUtilities.cpp

Issue 302643004: [SVG2] Allow leading and trailing whitespace in svg attributes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@relax_todouble_wtf
Patch Set: split tests to combat slow xp trybots Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/svg/SVGParserUtilities.h ('k') | Source/core/svg/SVGPoint.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2002, 2003 The Karbon Developers 2 * Copyright (C) 2002, 2003 The Karbon Developers
3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> 4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org>
5 * Copyright (C) 2007, 2009, 2013 Apple Inc. All rights reserved. 5 * Copyright (C) 2007, 2009, 2013 Apple Inc. All rights reserved.
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 25 matching lines...) Expand all
36 static inline bool isValidRange(const FloatType& x) 36 static inline bool isValidRange(const FloatType& x)
37 { 37 {
38 static const FloatType max = std::numeric_limits<FloatType>::max(); 38 static const FloatType max = std::numeric_limits<FloatType>::max();
39 return x >= -max && x <= max; 39 return x >= -max && x <= max;
40 } 40 }
41 41
42 // We use this generic parseNumber function to allow the Path parsing code to wo rk 42 // We use this generic parseNumber function to allow the Path parsing code to wo rk
43 // at a higher precision internally, without any unnecessary runtime cost or cod e 43 // at a higher precision internally, without any unnecessary runtime cost or cod e
44 // complexity. 44 // complexity.
45 template <typename CharType, typename FloatType> 45 template <typename CharType, typename FloatType>
46 static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatT ype& number, bool skip) 46 static bool genericParseNumber(const CharType*& ptr, const CharType* end, FloatT ype& number, WhitespaceMode mode)
47 { 47 {
48 FloatType integer, decimal, frac, exponent; 48 FloatType integer, decimal, frac, exponent;
49 int sign, expsign; 49 int sign, expsign;
50 const CharType* start = ptr; 50 const CharType* start = ptr;
51 51
52 exponent = 0; 52 exponent = 0;
53 integer = 0; 53 integer = 0;
54 frac = 1; 54 frac = 1;
55 decimal = 0; 55 decimal = 0;
56 sign = 1; 56 sign = 1;
57 expsign = 1; 57 expsign = 1;
58 58
59 if (mode & AllowLeadingWhitespace)
60 skipOptionalSVGSpaces(ptr, end);
61
59 // read the sign 62 // read the sign
60 if (ptr < end && *ptr == '+') 63 if (ptr < end && *ptr == '+')
61 ptr++; 64 ptr++;
62 else if (ptr < end && *ptr == '-') { 65 else if (ptr < end && *ptr == '-') {
63 ptr++; 66 ptr++;
64 sign = -1; 67 sign = -1;
65 } 68 }
66 69
67 if (ptr == end || ((*ptr < '0' || *ptr > '9') && *ptr != '.')) 70 if (ptr == end || ((*ptr < '0' || *ptr > '9') && *ptr != '.'))
68 // The first character of a number must be one of [0-9+-.] 71 // The first character of a number must be one of [0-9+-.]
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 if (exponent) 132 if (exponent)
130 number *= static_cast<FloatType>(pow(10.0, expsign * static_cast<int>(ex ponent))); 133 number *= static_cast<FloatType>(pow(10.0, expsign * static_cast<int>(ex ponent)));
131 134
132 // Don't return Infinity() or NaN(). 135 // Don't return Infinity() or NaN().
133 if (!isValidRange(number)) 136 if (!isValidRange(number))
134 return false; 137 return false;
135 138
136 if (start == ptr) 139 if (start == ptr)
137 return false; 140 return false;
138 141
139 if (skip) 142 if (mode & AllowTrailingWhitespace)
140 skipOptionalSVGSpacesOrDelimiter(ptr, end); 143 skipOptionalSVGSpacesOrDelimiter(ptr, end);
141 144
142 return true; 145 return true;
143 } 146 }
144 147
145 template <typename CharType> 148 template <typename CharType>
146 bool parseSVGNumber(CharType* begin, size_t length, double& number) 149 bool parseSVGNumber(CharType* begin, size_t length, double& number)
147 { 150 {
148 const CharType* ptr = begin; 151 const CharType* ptr = begin;
149 const CharType* end = ptr + length; 152 const CharType* end = ptr + length;
150 return genericParseNumber(ptr, end, number, false); 153 return genericParseNumber(ptr, end, number, AllowLeadingAndTrailingWhitespac e);
151 } 154 }
152 155
153 // Explicitly instantiate the two flavors of parseSVGNumber() to satisfy externa l callers 156 // Explicitly instantiate the two flavors of parseSVGNumber() to satisfy externa l callers
154 template bool parseSVGNumber(LChar* begin, size_t length, double&); 157 template bool parseSVGNumber(LChar* begin, size_t length, double&);
155 template bool parseSVGNumber(UChar* begin, size_t length, double&); 158 template bool parseSVGNumber(UChar* begin, size_t length, double&);
156 159
157 bool parseNumber(const LChar*& ptr, const LChar* end, float& number, bool skip) 160 bool parseNumber(const LChar*& ptr, const LChar* end, float& number, WhitespaceM ode mode)
158 { 161 {
159 return genericParseNumber(ptr, end, number, skip); 162 return genericParseNumber(ptr, end, number, mode);
160 } 163 }
161 164
162 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip) 165 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, WhitespaceM ode mode)
163 { 166 {
164 return genericParseNumber(ptr, end, number, skip); 167 return genericParseNumber(ptr, end, number, mode);
165 } 168 }
166 169
167 // only used to parse largeArcFlag and sweepFlag which must be a "0" or "1" 170 // only used to parse largeArcFlag and sweepFlag which must be a "0" or "1"
168 // and might not have any whitespace/comma after it 171 // and might not have any whitespace/comma after it
169 template <typename CharType> 172 template <typename CharType>
170 bool genericParseArcFlag(const CharType*& ptr, const CharType* end, bool& flag) 173 bool genericParseArcFlag(const CharType*& ptr, const CharType* end, bool& flag)
171 { 174 {
172 if (ptr >= end) 175 if (ptr >= end)
173 return false; 176 return false;
174 const CharType flagChar = *ptr++; 177 const CharType flagChar = *ptr++;
(...skipping 20 matching lines...) Expand all
195 } 198 }
196 199
197 template<typename CharType> 200 template<typename CharType>
198 static bool genericParseNumberOptionalNumber(const CharType*& ptr, const CharTyp e* end, float& x, float& y) 201 static bool genericParseNumberOptionalNumber(const CharType*& ptr, const CharTyp e* end, float& x, float& y)
199 { 202 {
200 if (!parseNumber(ptr, end, x)) 203 if (!parseNumber(ptr, end, x))
201 return false; 204 return false;
202 205
203 if (ptr == end) 206 if (ptr == end)
204 y = x; 207 y = x;
205 else if (!parseNumber(ptr, end, y, false)) 208 else if (!parseNumber(ptr, end, y, AllowLeadingAndTrailingWhitespace))
206 return false; 209 return false;
207 210
208 return ptr == end; 211 return ptr == end;
209 } 212 }
210 213
211 bool parseNumberOptionalNumber(const String& string, float& x, float& y) 214 bool parseNumberOptionalNumber(const String& string, float& x, float& y)
212 { 215 {
213 if (string.isEmpty()) 216 if (string.isEmpty())
214 return false; 217 return false;
218
215 if (string.is8Bit()) { 219 if (string.is8Bit()) {
216 const LChar* ptr = string.characters8(); 220 const LChar* ptr = string.characters8();
217 const LChar* end = ptr + string.length(); 221 const LChar* end = ptr + string.length();
218 return genericParseNumberOptionalNumber(ptr, end, x, y); 222 return genericParseNumberOptionalNumber(ptr, end, x, y);
219 } 223 }
220 const UChar* ptr = string.characters16(); 224 const UChar* ptr = string.characters16();
221 const UChar* end = ptr + string.length(); 225 const UChar* end = ptr + string.length();
222 return genericParseNumberOptionalNumber(ptr, end, x, y); 226 return genericParseNumberOptionalNumber(ptr, end, x, y);
223 } 227 }
224 228
225 template<typename CharType> 229 template<typename CharType>
230 bool genericParseNumberOrPercentage(const CharType*& ptr, const CharType* end, f loat& number)
231 {
232 if (genericParseNumber(ptr, end, number, AllowLeadingWhitespace)) {
233 if (ptr == end)
234 return true;
235
236 bool isPercentage = (*ptr == '%');
237 if (isPercentage)
238 ptr++;
239
240 skipOptionalSVGSpaces(ptr, end);
241
242 if (isPercentage)
243 number /= 100.f;
244
245 return ptr == end;
246 }
247
248 return false;
249 }
250
251 bool parseNumberOrPercentage(const String& string, float& number)
252 {
253 if (string.isEmpty())
254 return false;
255
256 if (string.is8Bit()) {
257 const LChar* ptr = string.characters8();
258 const LChar* end = ptr + string.length();
259 return genericParseNumberOrPercentage(ptr, end, number);
260 }
261 const UChar* ptr = string.characters16();
262 const UChar* end = ptr + string.length();
263 return genericParseNumberOrPercentage(ptr, end, number);
264 }
265
266 template<typename CharType>
226 static bool parseGlyphName(const CharType*& ptr, const CharType* end, HashSet<St ring>& values) 267 static bool parseGlyphName(const CharType*& ptr, const CharType* end, HashSet<St ring>& values)
227 { 268 {
228 skipOptionalSVGSpaces(ptr, end); 269 skipOptionalSVGSpaces(ptr, end);
229 270
230 while (ptr < end) { 271 while (ptr < end) {
231 // Leading and trailing white space, and white space before and after se parators, will be ignored. 272 // Leading and trailing white space, and white space before and after se parators, will be ignored.
232 const CharType* inputStart = ptr; 273 const CharType* inputStart = ptr;
233 while (ptr < end && *ptr != ',') 274 while (ptr < end && *ptr != ',')
234 ++ptr; 275 ++ptr;
235 276
236 if (ptr == inputStart) 277 if (ptr == inputStart)
237 break; 278 break;
238 279
239 // walk backwards from the ; to ignore any whitespace 280 // walk backwards from the ; to ignore any whitespace
240 const CharType* inputEnd = ptr - 1; 281 const CharType* inputEnd = ptr - 1;
241 while (inputStart < inputEnd && isSVGSpace(*inputEnd)) 282 while (inputStart < inputEnd && isHTMLSpace<CharType>(*inputEnd))
242 --inputEnd; 283 --inputEnd;
243 284
244 values.add(String(inputStart, inputEnd - inputStart + 1)); 285 values.add(String(inputStart, inputEnd - inputStart + 1));
245 skipOptionalSVGSpacesOrDelimiter(ptr, end, ','); 286 skipOptionalSVGSpacesOrDelimiter(ptr, end, ',');
246 } 287 }
247 288
248 return true; 289 return true;
249 } 290 }
250 291
251 bool parseGlyphName(const String& input, HashSet<String>& values) 292 bool parseGlyphName(const String& input, HashSet<String>& values)
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 // Leading and trailing white space, and white space before and after se micolon separators, will be ignored. 424 // Leading and trailing white space, and white space before and after se micolon separators, will be ignored.
384 const CharType* inputStart = ptr; 425 const CharType* inputStart = ptr;
385 while (ptr < end && *ptr != seperator) // careful not to ignore whitespa ce inside inputs 426 while (ptr < end && *ptr != seperator) // careful not to ignore whitespa ce inside inputs
386 ptr++; 427 ptr++;
387 428
388 if (ptr == inputStart) 429 if (ptr == inputStart)
389 break; 430 break;
390 431
391 // walk backwards from the ; to ignore any whitespace 432 // walk backwards from the ; to ignore any whitespace
392 const CharType* inputEnd = ptr - 1; 433 const CharType* inputEnd = ptr - 1;
393 while (inputStart < inputEnd && isSVGSpace(*inputEnd)) 434 while (inputStart < inputEnd && isHTMLSpace<CharType>(*inputEnd))
394 inputEnd--; 435 inputEnd--;
395 436
396 values.append(String(inputStart, inputEnd - inputStart + 1)); 437 values.append(String(inputStart, inputEnd - inputStart + 1));
397 skipOptionalSVGSpacesOrDelimiter(ptr, end, seperator); 438 skipOptionalSVGSpacesOrDelimiter(ptr, end, seperator);
398 } 439 }
399 440
400 return values; 441 return values;
401 } 442 }
402 443
403 Vector<String> parseDelimitedString(const String& input, const char seperator) 444 Vector<String> parseDelimitedString(const String& input, const char seperator)
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 parseAndSkipTransformType(ptr, end, type); 563 parseAndSkipTransformType(ptr, end, type);
523 } else { 564 } else {
524 const UChar* ptr = string.characters16(); 565 const UChar* ptr = string.characters16();
525 const UChar* end = ptr + string.length(); 566 const UChar* end = ptr + string.length();
526 parseAndSkipTransformType(ptr, end, type); 567 parseAndSkipTransformType(ptr, end, type);
527 } 568 }
528 return type; 569 return type;
529 } 570 }
530 571
531 } 572 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGParserUtilities.h ('k') | Source/core/svg/SVGPoint.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698