summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-10-28 14:57:00 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-10-28 14:57:00 -0700
commite1fab56ffa50364fd08d4a935a2a3339f7faa509 (patch)
treeb2ca7e4bc1da69ba1d7a00391ba0c4f936b9e657 /src
parent83046073c50f62a7b1fde665c1340170c4624a17 (diff)
parent906e685ce43092812bf403016057376d0657a671 (diff)
downloadart-e1fab56ffa50364fd08d4a935a2a3339f7faa509.zip
art-e1fab56ffa50364fd08d4a935a2a3339f7faa509.tar.gz
art-e1fab56ffa50364fd08d4a935a2a3339f7faa509.tar.bz2
Merge "Fix the unintelligible IsValidClassName API by breaking it into three." into dalvik-dev
Diffstat (limited to 'src')
-rw-r--r--src/check_jni.cc4
-rw-r--r--src/java_lang_Class.cc2
-rw-r--r--src/utils.cc29
-rw-r--r--src/utils.h12
4 files changed, 25 insertions, 22 deletions
diff --git a/src/check_jni.cc b/src/check_jni.cc
index 15cc161..b6670e4 100644
--- a/src/check_jni.cc
+++ b/src/check_jni.cc
@@ -161,7 +161,7 @@ public:
* "[Ljava/lang/Object;".
*/
void CheckClassName(const char* className) {
- if (!IsValidClassName(className, true, false)) {
+ if (!IsValidJniClassName(className)) {
LOG(ERROR) << "JNI ERROR: illegal class name '" << className << "' (" << function_name_ << ")\n"
<< " (should be of the form 'java/lang/String', [Ljava/lang/String;' or '[[B')\n";
JniAbort();
@@ -241,7 +241,7 @@ public:
DCHECK(f->GetType() != NULL);
Class* c = o->GetClass();
if (c->FindInstanceField(f->GetName()->ToModifiedUtf8(), f->GetTypeDescriptor()) == NULL) {
- LOG(ERROR) << "JNI ERROR: jfieldID " << PrettyField(f)
+ LOG(ERROR) << "JNI ERROR: jfieldID " << PrettyField(f)
<< " not valid for an object of class " << PrettyTypeOf(o);
JniAbort();
}
diff --git a/src/java_lang_Class.cc b/src/java_lang_Class.cc
index eccf977..1700ce1 100644
--- a/src/java_lang_Class.cc
+++ b/src/java_lang_Class.cc
@@ -38,7 +38,7 @@ jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean initia
// We need to validate and convert the name (from x.y.z to x/y/z). This
// is especially handy for array types, since we want to avoid
// auto-generating bogus array classes.
- if (!IsValidClassName(name.c_str(), true, true)) {
+ if (!IsValidBinaryClassName(name.c_str())) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/ClassNotFoundException;",
"Invalid name: %s", name.c_str());
return NULL;
diff --git a/src/utils.cc b/src/utils.cc
index 4c65036..c37343c 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -274,8 +274,6 @@ std::string JniLongName(const Method* m) {
return long_name;
}
-namespace {
-
// Helper for IsValidMemberNameUtf8(), a bit vector indicating valid low ascii.
uint32_t DEX_MEMBER_VALID_LOW_ASCII[4] = {
0x00000000, // 00..1f low control characters; nothing valid
@@ -355,11 +353,8 @@ bool IsValidMemberNameUtf8(const char** pUtf8Ptr) {
return IsValidMemberNameUtf8Slow(pUtf8Ptr);
}
-} // namespace
-
-bool IsValidClassName(const char* s, bool isClassName, bool dot_or_slash) {
- char separator = (dot_or_slash ? '.' : '/');
-
+enum ClassNameType { kName, kDescriptor };
+bool IsValidClassName(const char* s, ClassNameType type, char separator) {
int arrayCount = 0;
while (*s == '[') {
arrayCount++;
@@ -378,10 +373,10 @@ bool IsValidClassName(const char* s, bool isClassName, bool dot_or_slash) {
* format looks the same as a type descriptor in that case, so
* treat it as such.
*/
- isClassName = false;
+ type = kDescriptor;
}
- if (!isClassName) {
+ if (type == kDescriptor) {
/*
* We are looking for a descriptor. Either validate it as a
* single-character primitive type, or continue on to check the
@@ -427,7 +422,7 @@ bool IsValidClassName(const char* s, bool isClassName, bool dot_or_slash) {
* empty component (including the degenerate case of
* the empty string "").
*/
- return isClassName && !sepOrFirst;
+ return (type == kName) && !sepOrFirst;
case ';':
/*
* Invalid character for a class name, but the
@@ -436,7 +431,7 @@ bool IsValidClassName(const char* s, bool isClassName, bool dot_or_slash) {
* and that it doesn't end with an empty component
* (including the degenerate case of "L;").
*/
- return !isClassName && !sepOrFirst && (s[1] == '\0');
+ return (type == kDescriptor) && !sepOrFirst && (s[1] == '\0');
case '/':
case '.':
if (c != separator) {
@@ -460,6 +455,18 @@ bool IsValidClassName(const char* s, bool isClassName, bool dot_or_slash) {
}
}
+bool IsValidBinaryClassName(const char* s) {
+ return IsValidClassName(s, kName, '.');
+}
+
+bool IsValidJniClassName(const char* s) {
+ return IsValidClassName(s, kName, '/');
+}
+
+bool IsValidDescriptor(const char* s) {
+ return IsValidClassName(s, kDescriptor, '/');
+}
+
void Split(const std::string& s, char delim, std::vector<std::string>& result) {
const char* p = s.data();
const char* end = p + s.size();
diff --git a/src/utils.h b/src/utils.h
index bb307d1..f747ae8 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -190,14 +190,10 @@ std::string DotToDescriptor(const char* class_name);
// Turn "Ljava/lang/String;" into "java.lang.String".
std::string DescriptorToDot(const std::string& descriptor);
-// Tests whether 's' is a valid class name.
-// name_or_descriptor
-// true => "java/lang/String"
-// false => "Ljava/lang/String;" (i.e. "descriptor")
-// dot_or_slash
-// true => "java.lang.String"
-// false => "java/lang/String" (i.e. "dot or slash")
-bool IsValidClassName(const char* s, bool name_or_descriptor, bool dot_or_slash);
+// Tests for whether 's' is a valid class name in the three common forms:
+bool IsValidBinaryClassName(const char* s); // "java.lang.String"
+bool IsValidJniClassName(const char* s); // "java/lang/String"
+bool IsValidDescriptor(const char* s); // "Ljava/lang/String;"
// Returns the JNI native function name for the non-overloaded method 'm'.
std::string JniShortName(const Method* m);