diff options
author | 2023-04-05 06:17:45 +0100 | |
---|---|---|
committer | 2023-04-05 11:53:49 +0000 | |
commit | 6df5f2da76cc1e9d1a7bee74da5cc13f5761701a (patch) | |
tree | d0197d82e634d0366281b934fe00cbb622ab40e1 | |
parent | cf37e10e72c8be8687ec64cbe5e51c2511b4ccca (diff) |
Record field is immutable via java.lang.reflect.Field API
Bug: 272698028
Test: atest CtsLibcoreTestCases:crossvmtest
Change-Id: Ib97518d487947848011af70bc2de80504173cb52
-rw-r--r-- | runtime/native/java_lang_reflect_Field.cc | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index 946a4e4c9d..f2603d4c48 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -340,6 +340,26 @@ ALWAYS_INLINE inline static void SetFieldValue(ObjPtr<mirror::Object> o, } } +ALWAYS_INLINE inline static bool ThrowIAEIfRecordFinalField(ObjPtr<mirror::Field> field) + REQUIRES_SHARED(Locks::mutator_lock_) { + if (!(field->IsFinal())) { + return false; + } + ObjPtr<mirror::Class> declaring_class = field->GetDeclaringClass(); + DCHECK(declaring_class != nullptr); + if (!(declaring_class->IsRecordClass())) { + return false; + } + + ThrowIllegalAccessException( + StringPrintf("Cannot set %s field %s of record class %s", + PrettyJavaAccessFlags(field->GetAccessFlags()).c_str(), + ArtField::PrettyField(field->GetArtField()).c_str(), + declaring_class->PrettyClass().c_str()).c_str()); + + return true; +} + static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { ScopedFastNativeObjectAccess soa(env); ObjPtr<mirror::Field> f = soa.Decode<mirror::Field>(javaField); @@ -349,6 +369,10 @@ static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject j DCHECK(soa.Self()->IsExceptionPending()); return; } + if (ThrowIAEIfRecordFinalField(f)) { + DCHECK(soa.Self()->IsExceptionPending()); + return; + } ObjPtr<mirror::Class> field_type; const char* field_type_descriptor = f->GetArtField()->GetTypeDescriptor(); Primitive::Type field_prim_type = Primitive::GetType(field_type_descriptor[0]); @@ -389,6 +413,10 @@ static void SetPrimitiveField(JNIEnv* env, if (!CheckReceiver(soa, javaObj, &f, &o)) { return; } + if (ThrowIAEIfRecordFinalField(f)) { + DCHECK(soa.Self()->IsExceptionPending()); + return; + } Primitive::Type field_type = f->GetTypeAsPrimitiveType(); if (UNLIKELY(field_type == Primitive::kPrimNot)) { ThrowIllegalArgumentException( |