diff options
author | Elliott Hughes <enh@google.com> | 2009-11-13 17:07:00 -0800 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2009-11-13 17:12:48 -0800 |
commit | 845ce3cbfd6972542b275c95eddfbb6e94469737 (patch) | |
tree | 3f4c9ac0dd9f3787bacdb67b43ab76829ed4d608 /xml/src/main | |
parent | 25c2a2dcfb56959cf34e4e5e5496335be46c5e5c (diff) | |
download | libcore-845ce3cbfd6972542b275c95eddfbb6e94469737.zip libcore-845ce3cbfd6972542b275c95eddfbb6e94469737.tar.gz libcore-845ce3cbfd6972542b275c95eddfbb6e94469737.tar.bz2 |
Don't allocate arbitrary-length buffers on the stack.
A new LocalArray C++ class lets us specify a "reasonable" amount of stack to
use, but transparently fall back to using the heap if we need more space.
The three places I've chosen to use LocalArray in this patch are fairly
random; all they have in common is that they're the places where we call
GetStringUTFRegion. There are more places LocalArray will be useful: the
java.io.File JNI in particular.
Bug: 2257819
Diffstat (limited to 'xml/src/main')
-rw-r--r-- | xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp index 9192b1a..701dbd9 100644 --- a/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp +++ b/xml/src/main/native/org_apache_harmony_xml_ExpatParser.cpp @@ -16,9 +16,10 @@ #define LOG_TAG "ExpatParser" +#include "JNIHelp.h" +#include "LocalArray.h" #include "jni.h" #include "utils/Log.h" -#include "JNIHelp.h" #include <string.h> #include <utils/misc.h> @@ -1242,30 +1243,24 @@ static jint getAttributeIndexForQName(JNIEnv* env, jobject clazz, static jint getAttributeIndex(JNIEnv* env, jobject clazz, jint attributePointer, jstring uri, jstring localName) { const char** attributes = (const char**) attributePointer; - int uriLength = env->GetStringUTFLength(uri); - - if (uriLength == 0) { + int uriByteCount = env->GetStringUTFLength(uri); + if (uriByteCount == 0) { // If there's no URI, then a local name works just like a qName. return getAttributeIndexForQName( env, clazz, attributePointer, localName); } - int localNameLength = env->GetStringUTFLength(localName); - - // Create string in the same format used by Expat: "uri|localName" - // TODO: do we have a guarantee that uriLength and localNameLength are small? - char concatenated[uriLength + localNameLength + 2]; - - // Append uri. - env->GetStringUTFRegion(uri, 0, uriLength, concatenated); - - // Separator. - concatenated[uriLength] = '|'; - - // Append local name. - env->GetStringUTFRegion(localName, 0, localNameLength, - concatenated + uriLength + 1); - return findAttributeByName(attributes, concatenated); + // Create string in the same format used by Expat: "uri|localName\0". + // Note that we need byte counts to size the array but Unicode char counts + // for GetStringUTFRegion indexes and counts. + int localNameByteCount = env->GetStringUTFLength(localName); + LocalArray<1024> concatenated(uriByteCount + 1 + localNameByteCount + 1); + env->GetStringUTFRegion(uri, 0, env->GetStringLength(uri), &concatenated[0]); + concatenated[uriByteCount] = '|'; + env->GetStringUTFRegion(localName, 0, env->GetStringLength(localName), + &concatenated[uriByteCount + 1]); + + return findAttributeByName(attributes, &concatenated[0]); } /** |