diff options
author | Elliott Hughes <enh@google.com> | 2012-07-23 10:49:56 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2012-07-23 10:49:56 -0700 |
commit | 4f29f302c71d886db8ced57b6ede2d9cf41b30de (patch) | |
tree | de1053aa7ebe855947088a4d6cec8628a364c9bf | |
parent | b498bf420d28aeab14384fcc12db54d00ede03d3 (diff) | |
download | android_dalvik-4f29f302c71d886db8ced57b6ede2d9cf41b30de.tar.gz android_dalvik-4f29f302c71d886db8ced57b6ede2d9cf41b30de.tar.bz2 android_dalvik-4f29f302c71d886db8ced57b6ede2d9cf41b30de.zip |
Fix Method.getParameterAnnotations.
The dex format represents parameter annotations using an
annotation_set_ref_item for each parameter. According to the spec,
the item's annotation_offset can be "0 if there are no annotations for this
element". The Dalvik VM accepts 0 values in the verification step,
but Method#getParameterAnnotations then crashes with a segmentation fault.
Bug: http://code.google.com/p/android/issues/detail?id=35304
Change-Id: I0ac7336d369894520c8e17848ab6a91dbbd905e9
-rw-r--r-- | libdex/DexFile.h | 21 | ||||
-rw-r--r-- | vm/reflect/Annotation.cpp | 6 |
2 files changed, 20 insertions, 7 deletions
diff --git a/libdex/DexFile.h b/libdex/DexFile.h index 7a04f2a1f..809d4504f 100644 --- a/libdex/DexFile.h +++ b/libdex/DexFile.h @@ -809,14 +809,15 @@ DEX_INLINE const u1* dexGetClassData(const DexFile* pDexFile, DEX_INLINE const DexAnnotationSetItem* dexGetAnnotationSetItem( const DexFile* pDexFile, u4 offset) { + if (offset == 0) { + return NULL; + } return (const DexAnnotationSetItem*) (pDexFile->baseAddr + offset); } /* get the class' annotation set */ DEX_INLINE const DexAnnotationSetItem* dexGetClassAnnotationSet( const DexFile* pDexFile, const DexAnnotationsDirectoryItem* pAnnoDir) { - if (pAnnoDir->classAnnotationsOff == 0) - return NULL; return dexGetAnnotationSetItem(pDexFile, pAnnoDir->classAnnotationsOff); } @@ -903,16 +904,19 @@ DEX_INLINE int dexGetParameterAnnotationsSize(const DexFile* pDexFile, DEX_INLINE const DexAnnotationSetRefList* dexGetParameterAnnotationSetRefList( const DexFile* pDexFile, const DexParameterAnnotationsItem* pItem) { - return (const DexAnnotationSetRefList*) - (pDexFile->baseAddr + pItem->annotationsOff); + if (pItem->annotationsOff == 0) { + return NULL; + } + return (const DexAnnotationSetRefList*) (pDexFile->baseAddr + pItem->annotationsOff); } /* get method annotation list size */ DEX_INLINE int dexGetParameterAnnotationSetRefSize(const DexFile* pDexFile, const DexParameterAnnotationsItem* pItem) { - if (pItem->annotationsOff == 0) + if (pItem->annotationsOff == 0) { return 0; + } return dexGetParameterAnnotationSetRefList(pDexFile, pItem)->size; } @@ -943,8 +947,11 @@ DEX_INLINE u4 dexGetAnnotationOff( DEX_INLINE const DexAnnotationItem* dexGetAnnotationItem( const DexFile* pDexFile, const DexAnnotationSetItem* pAnnoSet, u4 idx) { - return (const DexAnnotationItem*) - (pDexFile->baseAddr + dexGetAnnotationOff(pAnnoSet, idx)); + u4 offset = dexGetAnnotationOff(pAnnoSet, idx); + if (offset == 0) { + return NULL; + } + return (const DexAnnotationItem*) (pDexFile->baseAddr + offset); } /* diff --git a/vm/reflect/Annotation.cpp b/vm/reflect/Annotation.cpp index 233db0881..453ddc5b5 100644 --- a/vm/reflect/Annotation.cpp +++ b/vm/reflect/Annotation.cpp @@ -2085,9 +2085,15 @@ static ArrayObject* processAnnotationSetRefList(const ClassObject* clazz, const DexAnnotationSetRefItem* pItem; const DexAnnotationSetItem* pAnnoSet; Object *annoSet; + DexAnnotationSetItem emptySet; + emptySet.size = 0; pItem = dexGetParameterAnnotationSetRef(pAnnoSetList, idx); pAnnoSet = dexGetSetRefItemItem(pDexFile, pItem); + if (pAnnoSet == NULL) { + pAnnoSet = &emptySet; + } + annoSet = (Object *)processAnnotationSet(clazz, pAnnoSet, kDexVisibilityRuntime); |