This is an automated email from the ASF dual-hosted git repository.

yufei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new 6137e42bb Core: Prevent AIOOBE for negative codes in 
PolarisEntityType, PolarisPrivilege, ReturnStatus (#2490)
6137e42bb is described below

commit 6137e42bb3d1a71274375e3efa49bf8edb5aa29f
Author: Honah (Jonas) J. <hon...@apache.org>
AuthorDate: Tue Sep 2 20:01:58 2025 -0500

    Core: Prevent AIOOBE for negative codes in PolarisEntityType, 
PolarisPrivilege, ReturnStatus (#2490)
---
 .../polaris/core/entity/PolarisEntityType.java     |   2 +-
 .../polaris/core/entity/PolarisPrivilege.java      |   2 +-
 .../core/persistence/dao/entity/BaseResult.java    |   4 +-
 .../polaris/core/entity/PolarisEntityTypeTest.java |  51 +++++++++
 .../polaris/core/entity/PolarisPrivilegeTest.java  | 124 +++++++++++++++++++++
 .../persistence/dao/entity/ReturnStatusTest.java   |  57 ++++++++++
 6 files changed, 237 insertions(+), 3 deletions(-)

diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java
index fae2d66eb..e0e5990d2 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java
@@ -111,7 +111,7 @@ public enum PolarisEntityType {
   @JsonCreator
   public static @Nullable PolarisEntityType fromCode(int entityTypeCode) {
     // ensure it is within bounds
-    if (entityTypeCode >= REVERSE_MAPPING_ARRAY.length) {
+    if (entityTypeCode < 0 || entityTypeCode >= REVERSE_MAPPING_ARRAY.length) {
       return null;
     }
 
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java
index 88cf6083b..b7a51565b 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java
@@ -272,7 +272,7 @@ public enum PolarisPrivilege {
   @JsonCreator
   public static @Nullable PolarisPrivilege fromCode(int code) {
     // ensure it is within bounds
-    if (code >= REVERSE_MAPPING_ARRAY.length) {
+    if (code < 0 || code >= REVERSE_MAPPING_ARRAY.length) {
       return null;
     }
 
diff --git 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/dao/entity/BaseResult.java
 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/dao/entity/BaseResult.java
index a8f3d5aef..e747a2f80 100644
--- 
a/polaris-core/src/main/java/org/apache/polaris/core/persistence/dao/entity/BaseResult.java
+++ 
b/polaris-core/src/main/java/org/apache/polaris/core/persistence/dao/entity/BaseResult.java
@@ -156,7 +156,9 @@ public class BaseResult {
     }
 
     static ReturnStatus getStatus(int code) {
-      return code >= REVERSE_MAPPING_ARRAY.length ? null : 
REVERSE_MAPPING_ARRAY[code];
+      return (code < 0 || code >= REVERSE_MAPPING_ARRAY.length)
+          ? null
+          : REVERSE_MAPPING_ARRAY[code];
     }
   }
 }
diff --git 
a/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisEntityTypeTest.java
 
b/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisEntityTypeTest.java
new file mode 100644
index 000000000..c2b9cd6ea
--- /dev/null
+++ 
b/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisEntityTypeTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.polaris.core.entity;
+
+import java.util.stream.Stream;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class PolarisEntityTypeTest {
+
+  static Stream<Arguments> entityTypes() {
+    return Stream.of(
+        Arguments.of(-1, null),
+        Arguments.of(0, PolarisEntityType.NULL_TYPE),
+        Arguments.of(1, PolarisEntityType.ROOT),
+        Arguments.of(2, PolarisEntityType.PRINCIPAL),
+        Arguments.of(3, PolarisEntityType.PRINCIPAL_ROLE),
+        Arguments.of(4, PolarisEntityType.CATALOG),
+        Arguments.of(5, PolarisEntityType.CATALOG_ROLE),
+        Arguments.of(6, PolarisEntityType.NAMESPACE),
+        Arguments.of(7, PolarisEntityType.TABLE_LIKE),
+        Arguments.of(8, PolarisEntityType.TASK),
+        Arguments.of(9, PolarisEntityType.FILE),
+        Arguments.of(10, PolarisEntityType.POLICY),
+        Arguments.of(11, null));
+  }
+
+  @ParameterizedTest
+  @MethodSource("entityTypes")
+  public void testFromCode(int code, PolarisEntityType expected) {
+    
Assertions.assertThat(PolarisEntityType.fromCode(code)).isEqualTo(expected);
+  }
+}
diff --git 
a/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisPrivilegeTest.java
 
b/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisPrivilegeTest.java
new file mode 100644
index 000000000..70c52e911
--- /dev/null
+++ 
b/polaris-core/src/test/java/org/apache/polaris/core/entity/PolarisPrivilegeTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.polaris.core.entity;
+
+import java.util.stream.Stream;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class PolarisPrivilegeTest {
+
+  static Stream<Arguments> polarisPrivileges() {
+    return Stream.of(
+        Arguments.of(-1, null),
+        Arguments.of(1, PolarisPrivilege.SERVICE_MANAGE_ACCESS),
+        Arguments.of(2, PolarisPrivilege.CATALOG_MANAGE_ACCESS),
+        Arguments.of(3, PolarisPrivilege.CATALOG_ROLE_USAGE),
+        Arguments.of(4, PolarisPrivilege.PRINCIPAL_ROLE_USAGE),
+        Arguments.of(5, PolarisPrivilege.NAMESPACE_CREATE),
+        Arguments.of(6, PolarisPrivilege.TABLE_CREATE),
+        Arguments.of(7, PolarisPrivilege.VIEW_CREATE),
+        Arguments.of(8, PolarisPrivilege.NAMESPACE_DROP),
+        Arguments.of(9, PolarisPrivilege.TABLE_DROP),
+        Arguments.of(10, PolarisPrivilege.VIEW_DROP),
+        Arguments.of(11, PolarisPrivilege.NAMESPACE_LIST),
+        Arguments.of(12, PolarisPrivilege.TABLE_LIST),
+        Arguments.of(13, PolarisPrivilege.VIEW_LIST),
+        Arguments.of(14, PolarisPrivilege.NAMESPACE_READ_PROPERTIES),
+        Arguments.of(15, PolarisPrivilege.TABLE_READ_PROPERTIES),
+        Arguments.of(16, PolarisPrivilege.VIEW_READ_PROPERTIES),
+        Arguments.of(17, PolarisPrivilege.NAMESPACE_WRITE_PROPERTIES),
+        Arguments.of(18, PolarisPrivilege.TABLE_WRITE_PROPERTIES),
+        Arguments.of(19, PolarisPrivilege.VIEW_WRITE_PROPERTIES),
+        Arguments.of(20, PolarisPrivilege.TABLE_READ_DATA),
+        Arguments.of(21, PolarisPrivilege.TABLE_WRITE_DATA),
+        Arguments.of(22, PolarisPrivilege.NAMESPACE_FULL_METADATA),
+        Arguments.of(23, PolarisPrivilege.TABLE_FULL_METADATA),
+        Arguments.of(24, PolarisPrivilege.VIEW_FULL_METADATA),
+        Arguments.of(25, PolarisPrivilege.CATALOG_CREATE),
+        Arguments.of(26, PolarisPrivilege.CATALOG_DROP),
+        Arguments.of(27, PolarisPrivilege.CATALOG_LIST),
+        Arguments.of(28, PolarisPrivilege.CATALOG_READ_PROPERTIES),
+        Arguments.of(29, PolarisPrivilege.CATALOG_WRITE_PROPERTIES),
+        Arguments.of(30, PolarisPrivilege.CATALOG_FULL_METADATA),
+        Arguments.of(31, PolarisPrivilege.CATALOG_MANAGE_METADATA),
+        Arguments.of(32, PolarisPrivilege.CATALOG_MANAGE_CONTENT),
+        Arguments.of(33, PolarisPrivilege.PRINCIPAL_LIST_GRANTS),
+        Arguments.of(34, PolarisPrivilege.PRINCIPAL_ROLE_LIST_GRANTS),
+        Arguments.of(35, PolarisPrivilege.CATALOG_ROLE_LIST_GRANTS),
+        Arguments.of(36, PolarisPrivilege.CATALOG_LIST_GRANTS),
+        Arguments.of(37, PolarisPrivilege.NAMESPACE_LIST_GRANTS),
+        Arguments.of(38, PolarisPrivilege.TABLE_LIST_GRANTS),
+        Arguments.of(39, PolarisPrivilege.VIEW_LIST_GRANTS),
+        Arguments.of(40, PolarisPrivilege.CATALOG_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(41, 
PolarisPrivilege.NAMESPACE_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(42, PolarisPrivilege.TABLE_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(43, PolarisPrivilege.VIEW_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(44, PolarisPrivilege.PRINCIPAL_CREATE),
+        Arguments.of(45, PolarisPrivilege.PRINCIPAL_DROP),
+        Arguments.of(46, PolarisPrivilege.PRINCIPAL_LIST),
+        Arguments.of(47, PolarisPrivilege.PRINCIPAL_READ_PROPERTIES),
+        Arguments.of(48, PolarisPrivilege.PRINCIPAL_WRITE_PROPERTIES),
+        Arguments.of(49, PolarisPrivilege.PRINCIPAL_FULL_METADATA),
+        Arguments.of(50, 
PolarisPrivilege.PRINCIPAL_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(51, PolarisPrivilege.PRINCIPAL_MANAGE_GRANTS_FOR_GRANTEE),
+        Arguments.of(52, PolarisPrivilege.PRINCIPAL_ROTATE_CREDENTIALS),
+        Arguments.of(53, PolarisPrivilege.PRINCIPAL_RESET_CREDENTIALS),
+        Arguments.of(54, PolarisPrivilege.PRINCIPAL_ROLE_CREATE),
+        Arguments.of(55, PolarisPrivilege.PRINCIPAL_ROLE_DROP),
+        Arguments.of(56, PolarisPrivilege.PRINCIPAL_ROLE_LIST),
+        Arguments.of(57, PolarisPrivilege.PRINCIPAL_ROLE_READ_PROPERTIES),
+        Arguments.of(58, PolarisPrivilege.PRINCIPAL_ROLE_WRITE_PROPERTIES),
+        Arguments.of(59, PolarisPrivilege.PRINCIPAL_ROLE_FULL_METADATA),
+        Arguments.of(60, 
PolarisPrivilege.PRINCIPAL_ROLE_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(61, 
PolarisPrivilege.PRINCIPAL_ROLE_MANAGE_GRANTS_FOR_GRANTEE),
+        Arguments.of(62, PolarisPrivilege.CATALOG_ROLE_CREATE),
+        Arguments.of(63, PolarisPrivilege.CATALOG_ROLE_DROP),
+        Arguments.of(64, PolarisPrivilege.CATALOG_ROLE_LIST),
+        Arguments.of(65, PolarisPrivilege.CATALOG_ROLE_READ_PROPERTIES),
+        Arguments.of(66, PolarisPrivilege.CATALOG_ROLE_WRITE_PROPERTIES),
+        Arguments.of(67, PolarisPrivilege.CATALOG_ROLE_FULL_METADATA),
+        Arguments.of(68, 
PolarisPrivilege.CATALOG_ROLE_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(69, 
PolarisPrivilege.CATALOG_ROLE_MANAGE_GRANTS_FOR_GRANTEE),
+        Arguments.of(70, PolarisPrivilege.POLICY_CREATE),
+        Arguments.of(71, PolarisPrivilege.POLICY_READ),
+        Arguments.of(72, PolarisPrivilege.POLICY_DROP),
+        Arguments.of(73, PolarisPrivilege.POLICY_WRITE),
+        Arguments.of(74, PolarisPrivilege.POLICY_LIST),
+        Arguments.of(75, PolarisPrivilege.POLICY_FULL_METADATA),
+        Arguments.of(76, PolarisPrivilege.POLICY_ATTACH),
+        Arguments.of(77, PolarisPrivilege.POLICY_DETACH),
+        Arguments.of(78, PolarisPrivilege.CATALOG_ATTACH_POLICY),
+        Arguments.of(79, PolarisPrivilege.NAMESPACE_ATTACH_POLICY),
+        Arguments.of(80, PolarisPrivilege.TABLE_ATTACH_POLICY),
+        Arguments.of(81, PolarisPrivilege.CATALOG_DETACH_POLICY),
+        Arguments.of(82, PolarisPrivilege.NAMESPACE_DETACH_POLICY),
+        Arguments.of(83, PolarisPrivilege.TABLE_DETACH_POLICY),
+        Arguments.of(84, PolarisPrivilege.POLICY_MANAGE_GRANTS_ON_SECURABLE),
+        Arguments.of(85, null));
+  }
+
+  @ParameterizedTest
+  @MethodSource("polarisPrivileges")
+  public void testFromCode(int code, PolarisPrivilege expected) {
+    Assertions.assertThat(PolarisPrivilege.fromCode(code)).isEqualTo(expected);
+  }
+}
diff --git 
a/polaris-core/src/test/java/org/apache/polaris/core/persistence/dao/entity/ReturnStatusTest.java
 
b/polaris-core/src/test/java/org/apache/polaris/core/persistence/dao/entity/ReturnStatusTest.java
new file mode 100644
index 000000000..a8fe83bc0
--- /dev/null
+++ 
b/polaris-core/src/test/java/org/apache/polaris/core/persistence/dao/entity/ReturnStatusTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.polaris.core.persistence.dao.entity;
+
+import java.util.stream.Stream;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+public class ReturnStatusTest {
+
+  static Stream<Arguments> returnStatuses() {
+    return Stream.of(
+        Arguments.of(-1, null),
+        Arguments.of(1, BaseResult.ReturnStatus.SUCCESS),
+        Arguments.of(2, BaseResult.ReturnStatus.UNEXPECTED_ERROR_SIGNALED),
+        Arguments.of(3, 
BaseResult.ReturnStatus.CATALOG_PATH_CANNOT_BE_RESOLVED),
+        Arguments.of(4, BaseResult.ReturnStatus.ENTITY_CANNOT_BE_RESOLVED),
+        Arguments.of(5, BaseResult.ReturnStatus.ENTITY_NOT_FOUND),
+        Arguments.of(6, BaseResult.ReturnStatus.GRANT_NOT_FOUND),
+        Arguments.of(7, BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS),
+        Arguments.of(8, BaseResult.ReturnStatus.ENTITY_UNDROPPABLE),
+        Arguments.of(9, BaseResult.ReturnStatus.NAMESPACE_NOT_EMPTY),
+        Arguments.of(10, BaseResult.ReturnStatus.CATALOG_NOT_EMPTY),
+        Arguments.of(11, 
BaseResult.ReturnStatus.TARGET_ENTITY_CONCURRENTLY_MODIFIED),
+        Arguments.of(12, BaseResult.ReturnStatus.ENTITY_CANNOT_BE_RENAMED),
+        Arguments.of(13, BaseResult.ReturnStatus.SUBSCOPE_CREDS_ERROR),
+        Arguments.of(14, BaseResult.ReturnStatus.POLICY_MAPPING_NOT_FOUND),
+        Arguments.of(15, 
BaseResult.ReturnStatus.POLICY_MAPPING_OF_SAME_TYPE_ALREADY_EXISTS),
+        Arguments.of(16, BaseResult.ReturnStatus.POLICY_HAS_MAPPINGS),
+        Arguments.of(17, null));
+  }
+
+  @ParameterizedTest
+  @MethodSource("returnStatuses")
+  public void testReturnStatusFromCode(int code, BaseResult.ReturnStatus 
expected) {
+    BaseResult.ReturnStatus actual = BaseResult.ReturnStatus.getStatus(code);
+    Assertions.assertThat(actual).isEqualTo(expected);
+  }
+}

Reply via email to