Merge "Improve error logging for parsing failures" into nyc-dev

This commit is contained in:
Doris Liu
2016-04-08 18:02:50 +00:00
committed by Android (Google) Code Review
6 changed files with 37 additions and 20 deletions

View File

@@ -31,12 +31,7 @@ public class PathParser {
throw new IllegalArgumentException("Path string can not be null.");
}
Path path = new Path();
boolean hasValidPathData = nParseStringForPath(path.mNativePath, pathString,
pathString.length());
if (!hasValidPathData) {
throw new IllegalArgumentException("Path string: " + pathString +
" does not contain valid path data");
}
nParseStringForPath(path.mNativePath, pathString, pathString.length());
return path;
}
@@ -104,7 +99,6 @@ public class PathParser {
}
super.finalize();
}
}
/**
@@ -123,7 +117,7 @@ public class PathParser {
}
// Native functions are defined below.
private static native boolean nParseStringForPath(long pathPtr, String pathString,
private static native void nParseStringForPath(long pathPtr, String pathString,
int stringLength);
private static native void nCreatePathFromPathData(long outPathPtr, long pathData);
private static native long nCreateEmptyPathData();

View File

@@ -176,6 +176,9 @@ static void setPathString(JNIEnv* env, jobject, jlong pathPtr, jstring inputStr,
PathParser::ParseResult result;
PathData data;
PathParser::getPathDataFromString(&data, &result, pathString, stringLength);
if (result.failureOccurred) {
doThrowIAE(env, result.failureMessage.c_str());
}
path->mutateStagingProperties()->setData(data);
env->ReleaseStringUTFChars(inputStr, pathString);
}

View File

@@ -15,6 +15,7 @@
*/
#include "jni.h"
#include "GraphicsJNI.h"
#include <PathParser.h>
#include <SkPath.h>
@@ -27,7 +28,7 @@ namespace android {
using namespace uirenderer;
static bool parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
static void parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring inputPathStr,
jint strLength) {
const char* pathString = env->GetStringUTFChars(inputPathStr, NULL);
SkPath* skPath = reinterpret_cast<SkPath*>(skPathHandle);
@@ -36,9 +37,8 @@ static bool parseStringForPath(JNIEnv* env, jobject, jlong skPathHandle, jstring
PathParser::parseStringForSkPath(skPath, &result, pathString, strLength);
env->ReleaseStringUTFChars(inputPathStr, pathString);
if (result.failureOccurred) {
ALOGE(result.failureMessage.c_str());
doThrowIAE(env, result.failureMessage.c_str());
}
return !result.failureOccurred;
}
static long createEmptyPathData(JNIEnv*, jobject) {
@@ -62,7 +62,7 @@ static long createPathDataFromStringPath(JNIEnv* env, jobject, jstring inputStr,
return reinterpret_cast<jlong>(pathData);
} else {
delete pathData;
ALOGE(result.failureMessage.c_str());
doThrowIAE(env, result.failureMessage.c_str());
return NULL;
}
}
@@ -100,7 +100,7 @@ static void setSkPathFromPathData(JNIEnv*, jobject, jlong outPathPtr, jlong path
}
static const JNINativeMethod gMethods[] = {
{"nParseStringForPath", "(JLjava/lang/String;I)Z", (void*)parseStringForPath},
{"nParseStringForPath", "(JLjava/lang/String;I)V", (void*)parseStringForPath},
{"nCreateEmptyPathData", "!()J", (void*)createEmptyPathData},
{"nCreatePathData", "!(J)J", (void*)createPathData},
{"nCreatePathDataFromString", "(Ljava/lang/String;I)J", (void*)createPathDataFromStringPath},

View File

@@ -156,6 +156,12 @@ 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::getPathDataFromString(PathData* data, ParseResult* result,
const char* pathStr, size_t strLen) {
if (pathStr == NULL) {
@@ -171,6 +177,12 @@ void PathParser::getPathDataFromString(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.
if (result->failureOccurred) {
return;
}
@@ -182,10 +194,15 @@ void PathParser::getPathDataFromString(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 "
+ std::to_string(start) + " of path: " + pathStr;
return;
}
data->verbs.push_back(pathStr[start]);
data->verbSizes.push_back(0);
}
return;
}
void PathParser::dump(const PathData& data) {
@@ -218,7 +235,8 @@ void PathParser::parseStringForSkPath(SkPath* skPath, ParseResult* result, const
// Check if there is valid data coming out of parsing the string.
if (pathData.verbs.size() == 0) {
result->failureOccurred = true;
result->failureMessage = "No verbs found in the string for pathData";
result->failureMessage = "No verbs found in the string for pathData: ";
result->failureMessage += pathStr;
return;
}
VectorDrawableUtils::verbsToPath(skPath, pathData);

View File

@@ -44,6 +44,7 @@ public:
ANDROID_API static void getPathDataFromString(PathData* outData, ParseResult* result,
const char* pathStr, size_t strLength);
static void dump(const PathData& data);
static bool isVerbValid(char verb);
};
}; // namespace uirenderer

View File

@@ -231,11 +231,12 @@ struct StringPath {
};
const StringPath sStringPaths[] = {
{"3e...3", false},
{"L.M.F.A.O", false},
{"m 1 1", true},
{"z", true},
{"1-2e34567", false}
{"3e...3", false}, // Not starting with a verb and ill-formatted float
{"L.M.F.A.O", false}, // No floats following verbs
{"m 1 1", true}, // Valid path data
{"z", true}, // Valid path data
{"1-2e34567", false}, // Not starting with a verb and ill-formatted float
{"f 4 5", false} // Invalid verb
};