| 3053 | } |
| 3054 | |
| 3055 | bool DexFileVerifier::CheckMethodAccessFlags(uint32_t method_index, |
| 3056 | uint32_t method_access_flags, |
| 3057 | uint32_t class_access_flags, |
| 3058 | uint32_t constructor_flags_by_name, |
| 3059 | bool has_code, |
| 3060 | bool expect_direct, |
| 3061 | std::string* error_msg) { |
| 3062 | // Generally sort out >16-bit flags, except dex knows Constructor and DeclaredSynchronized. |
| 3063 | constexpr uint32_t kAllMethodFlags = |
| 3064 | kAccJavaFlagsMask | kAccConstructor | kAccDeclaredSynchronized; |
| 3065 | if ((method_access_flags & ~kAllMethodFlags) != 0) { |
| 3066 | *error_msg = StringPrintf("Bad method access_flags for %s: %x", |
| 3067 | GetMethodDescriptionOrError(begin_, header_, method_index).c_str(), |
| 3068 | method_access_flags); |
| 3069 | return false; |
| 3070 | } |
| 3071 | |
| 3072 | // Flags allowed on fields, in general. Other lower-16-bit flags are to be ignored. |
| 3073 | constexpr uint32_t kMethodAccessFlags = kAccPublic | |
| 3074 | kAccPrivate | |
| 3075 | kAccProtected | |
| 3076 | kAccStatic | |
| 3077 | kAccFinal | |
| 3078 | kAccSynthetic | |
| 3079 | kAccSynchronized | |
| 3080 | kAccBridge | |
| 3081 | kAccVarargs | |
| 3082 | kAccNative | |
| 3083 | kAccAbstract | |
| 3084 | kAccStrict; |
| 3085 | |
| 3086 | // Methods may have only one of public/protected/final. |
| 3087 | if (!CheckAtMostOneOfPublicProtectedPrivate(method_access_flags)) { |
| 3088 | *error_msg = StringPrintf("Method may have only one of public/protected/private, %s: %x", |
| 3089 | GetMethodDescriptionOrError(begin_, header_, method_index).c_str(), |
| 3090 | method_access_flags); |
| 3091 | return false; |
| 3092 | } |
| 3093 | |
| 3094 | constexpr uint32_t kConstructorFlags = kAccStatic | kAccConstructor; |
| 3095 | const bool is_constructor_by_name = (constructor_flags_by_name & kConstructorFlags) != 0; |
| 3096 | const bool is_clinit_by_name = constructor_flags_by_name == kConstructorFlags; |
| 3097 | |
| 3098 | // Only methods named "<clinit>" or "<init>" may be marked constructor. Note: we cannot enforce |
| 3099 | // the reverse for backwards compatibility reasons. |
| 3100 | if (((method_access_flags & kAccConstructor) != 0) && !is_constructor_by_name) { |
| 3101 | *error_msg = |
| 3102 | StringPrintf("Method %" PRIu32 "(%s) is marked constructor, but doesn't match name", |
| 3103 | method_index, |
| 3104 | GetMethodDescriptionOrError(begin_, header_, method_index).c_str()); |
| 3105 | return false; |
| 3106 | } |
| 3107 | |
| 3108 | if (is_constructor_by_name) { |
| 3109 | // Check that the static constructor (= static initializer) is named "<clinit>" and that the |
| 3110 | // instance constructor is called "<init>". |
| 3111 | bool is_static = (method_access_flags & kAccStatic) != 0; |
| 3112 | if (is_static ^ is_clinit_by_name) { |
nothing calls this directly
no test coverage detected