summaryrefslogtreecommitdiffstats
path: root/xml/src/main
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2009-11-13 17:07:00 -0800
committerElliott Hughes <enh@google.com>2009-11-13 17:12:48 -0800
commit845ce3cbfd6972542b275c95eddfbb6e94469737 (patch)
tree3f4c9ac0dd9f3787bacdb67b43ab76829ed4d608 /xml/src/main
parent25c2a2dcfb56959cf34e4e5e5496335be46c5e5c (diff)
downloadlibcore-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.cpp35
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]);
}
/**