Loading core/java/android/content/res/XmlBlock.java +157 −46 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.content.res; import static android.content.res.Resources.ID_NULL; import static android.system.OsConstants.EINVAL; import android.annotation.AnyRes; import android.annotation.NonNull; Loading @@ -28,6 +29,7 @@ import android.util.TypedValue; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -92,6 +94,16 @@ public final class XmlBlock implements AutoCloseable { } } /** * Reference Error.h UNEXPECTED_NULL */ private static final int ERROR_NULL_DOCUMENT = Integer.MIN_VALUE + 8; /** * The reason not to ResXMLParser::BAD_DOCUMENT which is -1 is that other places use the same * value. Reference Error.h BAD_VALUE = -EINVAL */ private static final int ERROR_BAD_DOCUMENT = -EINVAL; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public final class Parser implements XmlResourceParser { Parser(long parseState, XmlBlock block) { Loading Loading @@ -168,7 +180,11 @@ public final class XmlBlock implements AutoCloseable { return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } public int getLineNumber() { return nativeGetLineNumber(mParseState); final int lineNumber = nativeGetLineNumber(mParseState); if (lineNumber == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return lineNumber; } public int getEventType() throws XmlPullParserException { return mEventType; Loading Loading @@ -203,7 +219,10 @@ public final class XmlBlock implements AutoCloseable { } @NonNull public String getAttributeNamespace(int index) { int id = nativeGetAttributeNamespace(mParseState, index); final int id = nativeGetAttributeNamespace(mParseState, index); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (DEBUG) System.out.println("getAttributeNamespace of " + index + " = " + id); if (id >= 0) return getSequenceString(mStrings.getSequence(id)); else if (id == -1) return ""; Loading @@ -211,8 +230,11 @@ public final class XmlBlock implements AutoCloseable { } @NonNull public String getAttributeName(int index) { int id = nativeGetAttributeName(mParseState, index); final int id = nativeGetAttributeName(mParseState, index); if (DEBUG) System.out.println("getAttributeName of " + index + " = " + id); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (id >= 0) return getSequenceString(mStrings.getSequence(id)); throw new IndexOutOfBoundsException(String.valueOf(index)); } Loading @@ -224,21 +246,38 @@ public final class XmlBlock implements AutoCloseable { return false; } public int getAttributeCount() { return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1; if (mEventType == START_TAG) { final int count = nativeGetAttributeCount(mParseState); if (count == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return count; } else { return -1; } } @NonNull public String getAttributeValue(int index) { int id = nativeGetAttributeStringValue(mParseState, index); final int id = nativeGetAttributeStringValue(mParseState, index); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (DEBUG) System.out.println("getAttributeValue of " + index + " = " + id); if (id >= 0) return getSequenceString(mStrings.getSequence(id)); // May be some other type... check and try to convert if so. int t = nativeGetAttributeDataType(mParseState, index); final int t = nativeGetAttributeDataType(mParseState, index); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (t == TypedValue.TYPE_NULL) { throw new IndexOutOfBoundsException(String.valueOf(index)); } int v = nativeGetAttributeData(mParseState, index); final int v = nativeGetAttributeData(mParseState, index); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return TypedValue.coerceToString(t, v); } public String getAttributeType(int index) { Loading Loading @@ -272,6 +311,9 @@ public final class XmlBlock implements AutoCloseable { return END_DOCUMENT; } int ev = nativeNext(mParseState); if (ev == ERROR_BAD_DOCUMENT) { throw new XmlPullParserException("Corrupt XML binary file"); } if (mDecNextDepth) { mDepth--; mDecNextDepth = false; Loading Loading @@ -338,7 +380,11 @@ public final class XmlBlock implements AutoCloseable { } public int getAttributeNameResource(int index) { return nativeGetAttributeResource(mParseState, index); final int resourceNameId = nativeGetAttributeResource(mParseState, index); if (resourceNameId == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return resourceNameId; } public int getAttributeListValue(String namespace, String attribute, Loading Loading @@ -393,8 +439,14 @@ public final class XmlBlock implements AutoCloseable { public int getAttributeListValue(int idx, String[] options, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); int v = nativeGetAttributeData(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (t == TypedValue.TYPE_STRING) { return XmlUtils.convertValueToList( mStrings.getSequence(v), options, defaultValue); Loading @@ -403,62 +455,99 @@ public final class XmlBlock implements AutoCloseable { } public boolean getAttributeBooleanValue(int idx, boolean defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx) != 0; if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v != 0; } return defaultValue; } public int getAttributeResourceValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t == TypedValue.TYPE_REFERENCE) { return nativeGetAttributeData(mParseState, idx); final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public int getAttributeIntValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx); if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public int getAttributeUnsignedIntValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx); if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public float getAttributeFloatValue(int idx, float defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t == TypedValue.TYPE_FLOAT) { return Float.intBitsToFloat( nativeGetAttributeData(mParseState, idx)); final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return Float.intBitsToFloat(v); } throw new RuntimeException("not a float!"); } @Nullable public String getIdAttribute() { int id = nativeGetIdAttribute(mParseState); final int id = nativeGetIdAttribute(mParseState); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } @Nullable public String getClassAttribute() { int id = nativeGetClassAttribute(mParseState); final int id = nativeGetClassAttribute(mParseState); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } Loading @@ -468,7 +557,11 @@ public final class XmlBlock implements AutoCloseable { } public int getStyleAttribute() { return nativeGetStyleAttribute(mParseState); final int styleAttributeId = nativeGetStyleAttribute(mParseState); if (styleAttributeId == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return styleAttributeId; } private String getSequenceString(@Nullable CharSequence str) { Loading Loading @@ -544,37 +637,55 @@ public final class XmlBlock implements AutoCloseable { // ----------- @FastNative ------------------ @FastNative private static native int nativeGetAttributeIndex( long state, String namespace, String name); // ----------- @CriticalNative ------------------ @CriticalNative /*package*/ static final native int nativeNext(long state); @FastNative @CriticalNative private static final native int nativeGetNamespace(long state); @FastNative @CriticalNative /*package*/ static final native int nativeGetName(long state); @FastNative @CriticalNative private static final native int nativeGetText(long state); @FastNative @CriticalNative private static final native int nativeGetLineNumber(long state); @FastNative @CriticalNative private static final native int nativeGetAttributeCount(long state); @FastNative @CriticalNative private static final native int nativeGetAttributeNamespace(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeName(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeResource(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeDataType(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeData(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeStringValue(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetIdAttribute(long state); @FastNative @CriticalNative private static final native int nativeGetClassAttribute(long state); @FastNative @CriticalNative private static final native int nativeGetStyleAttribute(long state); @FastNative private static final native int nativeGetAttributeIndex(long state, String namespace, String name); @FastNative @CriticalNative private static final native int nativeGetSourceResId(long state); } core/jni/android_util_XmlBlock.cpp +40 −73 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ #include <stdio.h> namespace android { constexpr int kNullDocument = UNEXPECTED_NULL; // The reason not to ResXMLParser::BAD_DOCUMENT which is -1 is that other places use the same value. constexpr int kBadDocument = BAD_VALUE; // ---------------------------------------------------------------------------- Loading Loading @@ -92,9 +95,7 @@ static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobjec return reinterpret_cast<jlong>(st); } static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeNext(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return ResXMLParser::END_DOCUMENT; Loading @@ -121,14 +122,10 @@ static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, } while (true); bad: jniThrowException(env, "org/xmlpull/v1/XmlPullParserException", "Corrupt XML binary file"); return ResXMLParser::BAD_DOCUMENT; return kBadDocument; } static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetNamespace(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -137,9 +134,7 @@ static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject cla return static_cast<jint>(st->getElementNamespaceID()); } static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetName(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -148,9 +143,7 @@ static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, return static_cast<jint>(st->getElementNameID()); } static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetText(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -159,97 +152,80 @@ static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, return static_cast<jint>(st->getTextID()); } static jint android_content_XmlBlock_nativeGetLineNumber(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetLineNumber(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getLineNumber()); } static jint android_content_XmlBlock_nativeGetAttributeCount(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetAttributeCount( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeCount()); } static jint android_content_XmlBlock_nativeGetAttributeNamespace(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeNamespace( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNamespaceID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeName(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeName(CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNameID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeResource(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeResource( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNameResID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeDataType(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeDataType( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeDataType(idx)); } static jint android_content_XmlBlock_nativeGetAttributeData(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeData(CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeData(idx)); } static jint android_content_XmlBlock_nativeGetAttributeStringValue(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeStringValue( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeValueStringID(idx)); Loading Loading @@ -286,39 +262,32 @@ static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobjec return idx; } static jint android_content_XmlBlock_nativeGetIdAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetIdAttribute(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfID(); return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetClassAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetClassAttribute( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfClass(); return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetStyleAttribute( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfStyle(); Loading @@ -336,9 +305,7 @@ static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobjec ? value.data : 0; } static jint android_content_XmlBlock_nativeGetSourceResId(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetSourceResId(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return 0; Loading Loading
core/java/android/content/res/XmlBlock.java +157 −46 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android.content.res; import static android.content.res.Resources.ID_NULL; import static android.system.OsConstants.EINVAL; import android.annotation.AnyRes; import android.annotation.NonNull; Loading @@ -28,6 +29,7 @@ import android.util.TypedValue; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.XmlUtils; import dalvik.annotation.optimization.CriticalNative; import dalvik.annotation.optimization.FastNative; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -92,6 +94,16 @@ public final class XmlBlock implements AutoCloseable { } } /** * Reference Error.h UNEXPECTED_NULL */ private static final int ERROR_NULL_DOCUMENT = Integer.MIN_VALUE + 8; /** * The reason not to ResXMLParser::BAD_DOCUMENT which is -1 is that other places use the same * value. Reference Error.h BAD_VALUE = -EINVAL */ private static final int ERROR_BAD_DOCUMENT = -EINVAL; @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public final class Parser implements XmlResourceParser { Parser(long parseState, XmlBlock block) { Loading Loading @@ -168,7 +180,11 @@ public final class XmlBlock implements AutoCloseable { return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } public int getLineNumber() { return nativeGetLineNumber(mParseState); final int lineNumber = nativeGetLineNumber(mParseState); if (lineNumber == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return lineNumber; } public int getEventType() throws XmlPullParserException { return mEventType; Loading Loading @@ -203,7 +219,10 @@ public final class XmlBlock implements AutoCloseable { } @NonNull public String getAttributeNamespace(int index) { int id = nativeGetAttributeNamespace(mParseState, index); final int id = nativeGetAttributeNamespace(mParseState, index); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (DEBUG) System.out.println("getAttributeNamespace of " + index + " = " + id); if (id >= 0) return getSequenceString(mStrings.getSequence(id)); else if (id == -1) return ""; Loading @@ -211,8 +230,11 @@ public final class XmlBlock implements AutoCloseable { } @NonNull public String getAttributeName(int index) { int id = nativeGetAttributeName(mParseState, index); final int id = nativeGetAttributeName(mParseState, index); if (DEBUG) System.out.println("getAttributeName of " + index + " = " + id); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (id >= 0) return getSequenceString(mStrings.getSequence(id)); throw new IndexOutOfBoundsException(String.valueOf(index)); } Loading @@ -224,21 +246,38 @@ public final class XmlBlock implements AutoCloseable { return false; } public int getAttributeCount() { return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1; if (mEventType == START_TAG) { final int count = nativeGetAttributeCount(mParseState); if (count == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return count; } else { return -1; } } @NonNull public String getAttributeValue(int index) { int id = nativeGetAttributeStringValue(mParseState, index); final int id = nativeGetAttributeStringValue(mParseState, index); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (DEBUG) System.out.println("getAttributeValue of " + index + " = " + id); if (id >= 0) return getSequenceString(mStrings.getSequence(id)); // May be some other type... check and try to convert if so. int t = nativeGetAttributeDataType(mParseState, index); final int t = nativeGetAttributeDataType(mParseState, index); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (t == TypedValue.TYPE_NULL) { throw new IndexOutOfBoundsException(String.valueOf(index)); } int v = nativeGetAttributeData(mParseState, index); final int v = nativeGetAttributeData(mParseState, index); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return TypedValue.coerceToString(t, v); } public String getAttributeType(int index) { Loading Loading @@ -272,6 +311,9 @@ public final class XmlBlock implements AutoCloseable { return END_DOCUMENT; } int ev = nativeNext(mParseState); if (ev == ERROR_BAD_DOCUMENT) { throw new XmlPullParserException("Corrupt XML binary file"); } if (mDecNextDepth) { mDepth--; mDecNextDepth = false; Loading Loading @@ -338,7 +380,11 @@ public final class XmlBlock implements AutoCloseable { } public int getAttributeNameResource(int index) { return nativeGetAttributeResource(mParseState, index); final int resourceNameId = nativeGetAttributeResource(mParseState, index); if (resourceNameId == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return resourceNameId; } public int getAttributeListValue(String namespace, String attribute, Loading Loading @@ -393,8 +439,14 @@ public final class XmlBlock implements AutoCloseable { public int getAttributeListValue(int idx, String[] options, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); int v = nativeGetAttributeData(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } if (t == TypedValue.TYPE_STRING) { return XmlUtils.convertValueToList( mStrings.getSequence(v), options, defaultValue); Loading @@ -403,62 +455,99 @@ public final class XmlBlock implements AutoCloseable { } public boolean getAttributeBooleanValue(int idx, boolean defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx) != 0; if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v != 0; } return defaultValue; } public int getAttributeResourceValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t == TypedValue.TYPE_REFERENCE) { return nativeGetAttributeData(mParseState, idx); final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public int getAttributeIntValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx); if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public int getAttributeUnsignedIntValue(int idx, int defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { return nativeGetAttributeData(mParseState, idx); if (t >= TypedValue.TYPE_FIRST_INT && t <= TypedValue.TYPE_LAST_INT) { final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return v; } return defaultValue; } public float getAttributeFloatValue(int idx, float defaultValue) { int t = nativeGetAttributeDataType(mParseState, idx); final int t = nativeGetAttributeDataType(mParseState, idx); if (t == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } // Note: don't attempt to convert any other types, because // we want to count on aapt doing the conversion for us. if (t == TypedValue.TYPE_FLOAT) { return Float.intBitsToFloat( nativeGetAttributeData(mParseState, idx)); final int v = nativeGetAttributeData(mParseState, idx); if (v == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return Float.intBitsToFloat(v); } throw new RuntimeException("not a float!"); } @Nullable public String getIdAttribute() { int id = nativeGetIdAttribute(mParseState); final int id = nativeGetIdAttribute(mParseState); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } @Nullable public String getClassAttribute() { int id = nativeGetClassAttribute(mParseState); final int id = nativeGetClassAttribute(mParseState); if (id == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return id >= 0 ? getSequenceString(mStrings.getSequence(id)) : null; } Loading @@ -468,7 +557,11 @@ public final class XmlBlock implements AutoCloseable { } public int getStyleAttribute() { return nativeGetStyleAttribute(mParseState); final int styleAttributeId = nativeGetStyleAttribute(mParseState); if (styleAttributeId == ERROR_NULL_DOCUMENT) { throw new NullPointerException("Null document"); } return styleAttributeId; } private String getSequenceString(@Nullable CharSequence str) { Loading Loading @@ -544,37 +637,55 @@ public final class XmlBlock implements AutoCloseable { // ----------- @FastNative ------------------ @FastNative private static native int nativeGetAttributeIndex( long state, String namespace, String name); // ----------- @CriticalNative ------------------ @CriticalNative /*package*/ static final native int nativeNext(long state); @FastNative @CriticalNative private static final native int nativeGetNamespace(long state); @FastNative @CriticalNative /*package*/ static final native int nativeGetName(long state); @FastNative @CriticalNative private static final native int nativeGetText(long state); @FastNative @CriticalNative private static final native int nativeGetLineNumber(long state); @FastNative @CriticalNative private static final native int nativeGetAttributeCount(long state); @FastNative @CriticalNative private static final native int nativeGetAttributeNamespace(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeName(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeResource(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeDataType(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeData(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetAttributeStringValue(long state, int idx); @FastNative @CriticalNative private static final native int nativeGetIdAttribute(long state); @FastNative @CriticalNative private static final native int nativeGetClassAttribute(long state); @FastNative @CriticalNative private static final native int nativeGetStyleAttribute(long state); @FastNative private static final native int nativeGetAttributeIndex(long state, String namespace, String name); @FastNative @CriticalNative private static final native int nativeGetSourceResId(long state); }
core/jni/android_util_XmlBlock.cpp +40 −73 Original line number Diff line number Diff line Loading @@ -28,6 +28,9 @@ #include <stdio.h> namespace android { constexpr int kNullDocument = UNEXPECTED_NULL; // The reason not to ResXMLParser::BAD_DOCUMENT which is -1 is that other places use the same value. constexpr int kBadDocument = BAD_VALUE; // ---------------------------------------------------------------------------- Loading Loading @@ -92,9 +95,7 @@ static jlong android_content_XmlBlock_nativeCreateParseState(JNIEnv* env, jobjec return reinterpret_cast<jlong>(st); } static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeNext(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return ResXMLParser::END_DOCUMENT; Loading @@ -121,14 +122,10 @@ static jint android_content_XmlBlock_nativeNext(JNIEnv* env, jobject clazz, } while (true); bad: jniThrowException(env, "org/xmlpull/v1/XmlPullParserException", "Corrupt XML binary file"); return ResXMLParser::BAD_DOCUMENT; return kBadDocument; } static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetNamespace(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -137,9 +134,7 @@ static jint android_content_XmlBlock_nativeGetNamespace(JNIEnv* env, jobject cla return static_cast<jint>(st->getElementNamespaceID()); } static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetName(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -148,9 +143,7 @@ static jint android_content_XmlBlock_nativeGetName(JNIEnv* env, jobject clazz, return static_cast<jint>(st->getElementNameID()); } static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetText(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return -1; Loading @@ -159,97 +152,80 @@ static jint android_content_XmlBlock_nativeGetText(JNIEnv* env, jobject clazz, return static_cast<jint>(st->getTextID()); } static jint android_content_XmlBlock_nativeGetLineNumber(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetLineNumber(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getLineNumber()); } static jint android_content_XmlBlock_nativeGetAttributeCount(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetAttributeCount( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeCount()); } static jint android_content_XmlBlock_nativeGetAttributeNamespace(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeNamespace( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNamespaceID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeName(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeName(CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNameID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeResource(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeResource( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeNameResID(idx)); } static jint android_content_XmlBlock_nativeGetAttributeDataType(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeDataType( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeDataType(idx)); } static jint android_content_XmlBlock_nativeGetAttributeData(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeData(CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeData(idx)); } static jint android_content_XmlBlock_nativeGetAttributeStringValue(JNIEnv* env, jobject clazz, jlong token, jint idx) { static jint android_content_XmlBlock_nativeGetAttributeStringValue( CRITICAL_JNI_PARAMS_COMMA jlong token, jint idx) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } return static_cast<jint>(st->getAttributeValueStringID(idx)); Loading Loading @@ -286,39 +262,32 @@ static jint android_content_XmlBlock_nativeGetAttributeIndex(JNIEnv* env, jobjec return idx; } static jint android_content_XmlBlock_nativeGetIdAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetIdAttribute(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfID(); return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetClassAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetClassAttribute( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfClass(); return idx >= 0 ? static_cast<jint>(st->getAttributeValueStringID(idx)) : -1; } static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetStyleAttribute( CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { jniThrowNullPointerException(env, NULL); return 0; return kNullDocument; } ssize_t idx = st->indexOfStyle(); Loading @@ -336,9 +305,7 @@ static jint android_content_XmlBlock_nativeGetStyleAttribute(JNIEnv* env, jobjec ? value.data : 0; } static jint android_content_XmlBlock_nativeGetSourceResId(JNIEnv* env, jobject clazz, jlong token) { static jint android_content_XmlBlock_nativeGetSourceResId(CRITICAL_JNI_PARAMS_COMMA jlong token) { ResXMLParser* st = reinterpret_cast<ResXMLParser*>(token); if (st == NULL) { return 0; Loading