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

Side by Side Diff: third_party/WebKit/Source/core/svg/SVGPathStringSource.cpp

Issue 1642463004: Extended error reporting for SVG path parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 */ 19 */
20 20
21 #include "core/svg/SVGPathStringSource.h" 21 #include "core/svg/SVGPathStringSource.h"
22 22
23 #include "core/svg/SVGParserUtilities.h" 23 #include "core/svg/SVGParserUtilities.h"
24 #include "platform/geometry/FloatPoint.h" 24 #include "platform/geometry/FloatPoint.h"
25 25
26 namespace blink { 26 namespace blink {
27 27
28 SVGPathStringSource::SVGPathStringSource(const String& string) 28 SVGPathStringSource::SVGPathStringSource(const String& string)
29 : m_string(string) 29 : m_is8BitSource(string.is8Bit())
30 , m_is8BitSource(string.is8Bit())
31 , m_seenError(false)
32 , m_previousCommand(PathSegUnknown) 30 , m_previousCommand(PathSegUnknown)
31 , m_string(string)
33 { 32 {
34 ASSERT(!string.isNull()); 33 ASSERT(!string.isNull());
35 34
36 if (m_is8BitSource) { 35 if (m_is8BitSource) {
37 m_current.m_character8 = string.characters8(); 36 m_current.m_character8 = string.characters8();
38 m_end.m_character8 = m_current.m_character8 + string.length(); 37 m_end.m_character8 = m_current.m_character8 + string.length();
39 } else { 38 } else {
40 m_current.m_character16 = string.characters16(); 39 m_current.m_character16 = string.characters16();
41 m_end.m_character16 = m_current.m_character16 + string.length(); 40 m_end.m_character16 = m_current.m_character16 + string.length();
42 } 41 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (previousCommand == PathSegMoveToRel) { 116 if (previousCommand == PathSegMoveToRel) {
118 nextCommand = PathSegLineToRel; 117 nextCommand = PathSegLineToRel;
119 return true; 118 return true;
120 } 119 }
121 nextCommand = previousCommand; 120 nextCommand = previousCommand;
122 return true; 121 return true;
123 } 122 }
124 return false; 123 return false;
125 } 124 }
126 125
126 void SVGPathStringSource::setErrorMark(SVGParseStatus status)
127 {
128 if (m_error.status() != SVGParseStatus::NoError)
129 return;
130 size_t locus = m_is8BitSource
131 ? m_current.m_character8 - m_string.characters8()
132 : m_current.m_character16 - m_string.characters16();
133 m_error = SVGParsingError(status, locus);
134 }
135
127 float SVGPathStringSource::parseNumberWithError() 136 float SVGPathStringSource::parseNumberWithError()
128 { 137 {
129 float numberValue = 0; 138 float numberValue = 0;
139 bool error;
130 if (m_is8BitSource) 140 if (m_is8BitSource)
131 m_seenError |= !parseNumber(m_current.m_character8, m_end.m_character8, numberValue); 141 error = !parseNumber(m_current.m_character8, m_end.m_character8, numberV alue);
132 else 142 else
133 m_seenError |= !parseNumber(m_current.m_character16, m_end.m_character16 , numberValue); 143 error = !parseNumber(m_current.m_character16, m_end.m_character16, numbe rValue);
144 if (UNLIKELY(error))
145 setErrorMark(SVGParseStatus::ExpectedNumber);
134 return numberValue; 146 return numberValue;
135 } 147 }
136 148
137 bool SVGPathStringSource::parseArcFlagWithError() 149 bool SVGPathStringSource::parseArcFlagWithError()
138 { 150 {
139 bool flagValue = false; 151 bool flagValue = false;
152 bool error;
140 if (m_is8BitSource) 153 if (m_is8BitSource)
141 m_seenError |= !parseArcFlag(m_current.m_character8, m_end.m_character8, flagValue); 154 error = !parseArcFlag(m_current.m_character8, m_end.m_character8, flagVa lue);
142 else 155 else
143 m_seenError |= !parseArcFlag(m_current.m_character16, m_end.m_character1 6, flagValue); 156 error = !parseArcFlag(m_current.m_character16, m_end.m_character16, flag Value);
157 if (UNLIKELY(error))
158 setErrorMark(SVGParseStatus::ExpectedArcFlag);
144 return flagValue; 159 return flagValue;
145 } 160 }
146 161
147 SVGPathSegType SVGPathStringSource::peekSegmentType() 162 SVGPathSegType SVGPathStringSource::peekSegmentType()
148 { 163 {
149 ASSERT(hasMoreData()); 164 ASSERT(hasMoreData());
150 // This won't work in all cases because of the state required to "detect" im plicit commands. 165 // This won't work in all cases because of the state required to "detect" im plicit commands.
151 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; 166 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16;
152 return parseSVGSegmentTypeHelper(lookahead); 167 SVGPathSegType segmentType = parseSVGSegmentTypeHelper(lookahead);
168 // Here we assume that this is only called via SVGPathParser::initialCommand IsMoveTo.
169 // TODO(fs): It ought to be possible to refactor away this entirely, and
170 // just handle this in parseSegment (which we sort of do already...) The
171 // only user is the method mentioned above.
f(malita) 2016/01/27 14:51:13 Yeah, it would be nice to get rid of this assumpti
fs 2016/01/27 14:57:56 I have some sort of (outline of a) plan for this [
172 if (segmentType != PathSegMoveToAbs && segmentType != PathSegMoveToRel)
173 setErrorMark(SVGParseStatus::ExpectedMoveToCommand);
174 return segmentType;
153 } 175 }
154 176
155 PathSegmentData SVGPathStringSource::parseSegment() 177 PathSegmentData SVGPathStringSource::parseSegment()
156 { 178 {
157 ASSERT(hasMoreData()); 179 ASSERT(hasMoreData());
158 PathSegmentData segment; 180 PathSegmentData segment;
159 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16; 181 unsigned lookahead = m_is8BitSource ? *m_current.m_character8 : *m_current.m _character16;
160 SVGPathSegType command = parseSVGSegmentTypeHelper(lookahead); 182 SVGPathSegType command = parseSVGSegmentTypeHelper(lookahead);
161 if (command == PathSegUnknown) { 183 if (command == PathSegUnknown) {
162 // Possibly an implicit command. Not allowed if this is the first comman d. 184 // Possibly an implicit command. Not allowed if this is the first comman d.
163 if (m_previousCommand == PathSegUnknown) 185 if (m_previousCommand == PathSegUnknown) {
186 setErrorMark(SVGParseStatus::ExpectedMoveToCommand);
164 return segment; 187 return segment;
165 if (!nextCommandHelper(lookahead, m_previousCommand, command)) 188 }
189 if (!nextCommandHelper(lookahead, m_previousCommand, command)) {
190 setErrorMark(SVGParseStatus::ExpectedPathCommand);
166 return segment; 191 return segment;
192 }
167 } else { 193 } else {
168 // Valid explicit command. 194 // Valid explicit command.
169 if (m_is8BitSource) 195 if (m_is8BitSource)
170 m_current.m_character8++; 196 m_current.m_character8++;
171 else 197 else
172 m_current.m_character16++; 198 m_current.m_character16++;
173 } 199 }
174 200
175 segment.command = m_previousCommand = command; 201 segment.command = m_previousCommand = command;
176 202
177 ASSERT(!m_seenError); 203 ASSERT(m_error.status() == SVGParseStatus::NoError);
178 204
179 switch (segment.command) { 205 switch (segment.command) {
180 case PathSegCurveToCubicRel: 206 case PathSegCurveToCubicRel:
181 case PathSegCurveToCubicAbs: 207 case PathSegCurveToCubicAbs:
182 segment.point1.setX(parseNumberWithError()); 208 segment.point1.setX(parseNumberWithError());
183 segment.point1.setY(parseNumberWithError()); 209 segment.point1.setY(parseNumberWithError());
184 /* fall through */ 210 /* fall through */
185 case PathSegCurveToCubicSmoothRel: 211 case PathSegCurveToCubicSmoothRel:
186 case PathSegCurveToCubicSmoothAbs: 212 case PathSegCurveToCubicSmoothAbs:
187 segment.point2.setX(parseNumberWithError()); 213 segment.point2.setX(parseNumberWithError());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 segment.setArcAngle(parseNumberWithError()); 247 segment.setArcAngle(parseNumberWithError());
222 segment.arcLarge = parseArcFlagWithError(); 248 segment.arcLarge = parseArcFlagWithError();
223 segment.arcSweep = parseArcFlagWithError(); 249 segment.arcSweep = parseArcFlagWithError();
224 segment.targetPoint.setX(parseNumberWithError()); 250 segment.targetPoint.setX(parseNumberWithError());
225 segment.targetPoint.setY(parseNumberWithError()); 251 segment.targetPoint.setY(parseNumberWithError());
226 break; 252 break;
227 case PathSegUnknown: 253 case PathSegUnknown:
228 ASSERT_NOT_REACHED(); 254 ASSERT_NOT_REACHED();
229 } 255 }
230 256
231 if (UNLIKELY(m_seenError)) 257 if (UNLIKELY(m_error.status() != SVGParseStatus::NoError))
232 segment.command = PathSegUnknown; 258 segment.command = PathSegUnknown;
233 return segment; 259 return segment;
234 } 260 }
235 261
236 } // namespace blink 262 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698