summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2024-06-06 12:55:45 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2024-06-06 13:44:53 +0000
commitf0c1e6d96ff5b30c7c54e309055b2b05001c43c8 (patch)
tree40f6365b469ca3c4f9f40342cfc9264bdbe17212
parent7650ceddfacb5c22b5e6f54458ae70f59eee5151 (diff)
Interface methods can also call protected methods.
Test: 856-clone Bug: 343164802 Change-Id: Ic4d93d4a7a6fbfbf854a36d01e28a16c16793307
-rw-r--r--runtime/mirror/class-inl.h11
-rw-r--r--test/856-clone/expected-stderr.txt0
-rw-r--r--test/856-clone/expected-stdout.txt0
-rw-r--r--test/856-clone/info.txt2
-rw-r--r--test/856-clone/src/Main.java29
5 files changed, 41 insertions, 1 deletions
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index 74776c14d4..b2c8e52351 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -1169,7 +1169,16 @@ inline bool Class::CanAccessMember(ObjPtr<Class> access_to, uint32_t member_flag
}
// Check for protected access from a sub-class, which may or may not be in the same package.
if (member_flags & kAccProtected) {
- if (!this->IsInterface() && this->IsSubClass(access_to)) {
+ // This implementation is not compliant. We should actually check whether
+ // the caller is a subclass of the static type of the receiver, instead of the declaring
+ // class of the method we are trying to access.
+ //
+ // For example, a class outside of java.lang should not ne able to access `Object.clone`,
+ // but this implementation allows it.
+ //
+ // To not break existing code, we decided not to fix this and accept the
+ // leniency.
+ if (access_to->IsAssignableFrom(this)) {
return true;
}
}
diff --git a/test/856-clone/expected-stderr.txt b/test/856-clone/expected-stderr.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/856-clone/expected-stderr.txt
diff --git a/test/856-clone/expected-stdout.txt b/test/856-clone/expected-stdout.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/856-clone/expected-stdout.txt
diff --git a/test/856-clone/info.txt b/test/856-clone/info.txt
new file mode 100644
index 0000000000..c94aab511f
--- /dev/null
+++ b/test/856-clone/info.txt
@@ -0,0 +1,2 @@
+Regression test for calling `Object.clone` from within an default interface
+method.
diff --git a/test/856-clone/src/Main.java b/test/856-clone/src/Main.java
new file mode 100644
index 0000000000..278cfd9542
--- /dev/null
+++ b/test/856-clone/src/Main.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+interface I {
+ default String[] myClone(String[] strings) {
+ return strings.clone();
+ }
+}
+
+class A implements I {}
+
+public class Main {
+ public static void main(String[] args) {
+ new A().myClone(args);
+ }
+}