Merge "More path validation for better error message" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
4f975de2f8
@@ -156,10 +156,63 @@ static void getFloats(std::vector<float>* outPoints, PathParser::ParseResult* re
|
||||
return;
|
||||
}
|
||||
|
||||
bool PathParser::isVerbValid(char verb) {
|
||||
verb = tolower(verb);
|
||||
return verb == 'a' || verb == 'c' || verb == 'h' || verb == 'l' || verb == 'm' || verb == 'q' ||
|
||||
verb == 's' || verb == 't' || verb == 'v' || verb == 'z';
|
||||
void PathParser::validateVerbAndPoints(char verb, size_t points, PathParser::ParseResult* result) {
|
||||
size_t numberOfPointsExpected = -1;
|
||||
switch (verb) {
|
||||
case 'z':
|
||||
case 'Z':
|
||||
numberOfPointsExpected = 0;
|
||||
break;
|
||||
case 'm':
|
||||
case 'l':
|
||||
case 't':
|
||||
case 'M':
|
||||
case 'L':
|
||||
case 'T':
|
||||
numberOfPointsExpected = 2;
|
||||
break;
|
||||
case 'h':
|
||||
case 'v':
|
||||
case 'H':
|
||||
case 'V':
|
||||
numberOfPointsExpected = 1;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
numberOfPointsExpected = 6;
|
||||
break;
|
||||
case 's':
|
||||
case 'q':
|
||||
case 'S':
|
||||
case 'Q':
|
||||
numberOfPointsExpected = 4;
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
numberOfPointsExpected = 7;
|
||||
break;
|
||||
default:
|
||||
result->failureOccurred = true;
|
||||
result->failureMessage += verb;
|
||||
result->failureMessage += " is not a valid verb. ";
|
||||
return;
|
||||
}
|
||||
if (numberOfPointsExpected == 0 && points == 0) {
|
||||
return;
|
||||
}
|
||||
if (numberOfPointsExpected > 0 && points % numberOfPointsExpected == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
result->failureOccurred = true;
|
||||
result->failureMessage += verb;
|
||||
result->failureMessage += " needs to be followed by ";
|
||||
if (numberOfPointsExpected > 0) {
|
||||
result->failureMessage += "a multiple of ";
|
||||
}
|
||||
result->failureMessage += std::to_string(numberOfPointsExpected)
|
||||
+ " floats. However, " + std::to_string(points)
|
||||
+ " float(s) are found. ";
|
||||
}
|
||||
|
||||
void PathParser::getPathDataFromAsciiString(PathData* data, ParseResult* result,
|
||||
@@ -186,13 +239,11 @@ void PathParser::getPathDataFromAsciiString(PathData* data, ParseResult* result,
|
||||
end = nextStart(pathStr, strLen, end);
|
||||
std::vector<float> points;
|
||||
getFloats(&points, result, pathStr, start, end);
|
||||
if (!isVerbValid(pathStr[start])) {
|
||||
result->failureOccurred = true;
|
||||
result->failureMessage = "Invalid pathData. Failure occurred at position " +
|
||||
std::to_string(start) + " of path: " + pathStr;
|
||||
}
|
||||
// If either verb or points is not valid, return immediately.
|
||||
validateVerbAndPoints(pathStr[start], points.size(), result);
|
||||
if (result->failureOccurred) {
|
||||
// If either verb or points is not valid, return immediately.
|
||||
result->failureMessage += "Failure occurred at position " +
|
||||
std::to_string(start) + " of path: " + pathStr;
|
||||
return;
|
||||
}
|
||||
data->verbs.push_back(pathStr[start]);
|
||||
@@ -203,9 +254,10 @@ void PathParser::getPathDataFromAsciiString(PathData* data, ParseResult* result,
|
||||
}
|
||||
|
||||
if ((end - start) == 1 && start < strLen) {
|
||||
if (!isVerbValid(pathStr[start])) {
|
||||
result->failureOccurred = true;
|
||||
result->failureMessage = "Invalid pathData. Failure occurred at position " +
|
||||
validateVerbAndPoints(pathStr[start], 0, result);
|
||||
if (result->failureOccurred) {
|
||||
// If either verb or points is not valid, return immediately.
|
||||
result->failureMessage += "Failure occurred at position " +
|
||||
std::to_string(start) + " of path: " + pathStr;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
ANDROID_API static void getPathDataFromAsciiString(PathData* outData, ParseResult* result,
|
||||
const char* pathStr, size_t strLength);
|
||||
static void dump(const PathData& data);
|
||||
static bool isVerbValid(char verb);
|
||||
static void validateVerbAndPoints(char verb, size_t points, ParseResult* result);
|
||||
};
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -242,7 +242,8 @@ const StringPath sStringPaths[] = {
|
||||
{"\n \t z", true}, // Valid path data with leading spaces
|
||||
{"1-2e34567", false}, // Not starting with a verb and ill-formatted float
|
||||
{"f 4 5", false}, // Invalid verb
|
||||
{"\r ", false} // Empty string
|
||||
{"\r ", false}, // Empty string
|
||||
{"L1,0 L1,1 L0,1 z M1000", false} // Not enough floats following verb M.
|
||||
};
|
||||
|
||||
static bool hasSameVerbs(const PathData& from, const PathData& to) {
|
||||
|
||||
Reference in New Issue
Block a user