You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polaris.apache.org by ad...@apache.org on 2026/04/17 10:06:08 UTC

(polaris) branch main updated: Remove double URL-decoding of table identifiers (#4210)

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

adutra 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 c949236c43 Remove double URL-decoding of table identifiers (#4210)
c949236c43 is described below

commit c949236c43475746bf5bcd47f98cb5a8fc7f9c89
Author: Alexandre Dutra <ad...@apache.org>
AuthorDate: Fri Apr 17 12:06:04 2026 +0200

    Remove double URL-decoding of table identifiers (#4210)
    
    This change fixes several double-decode issues when processing table identifiers in Polaris REST APIs.
    
    The REST framework (Jersey) already ULR-decodes path segments. For example, when a REST resource method such as `org.apache.polaris.service.catalog.api.IcebergRestCatalogApi.loadTable` is invoked, the parameters `namespace` and `table` are already URL-decoded. It is therefore incorrect to further URL-decode table identifiers.
---
 .../catalog/iceberg/IcebergCatalogAdapter.java     | 23 +++++++++++-----------
 .../catalog/policy/PolicyCatalogAdapter.java       | 20 ++++++++-----------
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
index e9344b1f3b..780a85054f 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
@@ -33,7 +33,6 @@ import org.apache.iceberg.MetadataUpdate;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.exceptions.BadRequestException;
-import org.apache.iceberg.rest.RESTUtil;
 import org.apache.iceberg.rest.requests.CommitTransactionRequest;
 import org.apache.iceberg.rest.requests.CreateNamespaceRequest;
 import org.apache.iceberg.rest.requests.CreateTableRequest;
@@ -323,7 +322,7 @@ public class IcebergCatalogAdapter
         parseAccessDelegationModes(accessDelegationMode);
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
 
     IfNoneMatch ifNoneMatch = IfNoneMatch.fromHeader(ifNoneMatchString);
 
@@ -370,7 +369,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     return withCatalog(
         securityContext,
         prefix,
@@ -390,7 +389,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     return withCatalog(
         securityContext,
         prefix,
@@ -461,7 +460,7 @@ public class IcebergCatalogAdapter
                 .toList());
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     return withCatalog(
         securityContext,
         prefix,
@@ -521,7 +520,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     Optional<String> refreshEndpoint =
         Optional.of(new PolarisResourcePaths(prefix).credentialsPath(tableIdentifier));
     return withCatalog(
@@ -539,7 +538,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(view));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, view);
     return withCatalog(
         securityContext, prefix, catalog -> Response.ok(catalog.loadView(tableIdentifier)).build());
   }
@@ -553,7 +552,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(view));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, view);
     return withCatalog(
         securityContext,
         prefix,
@@ -572,7 +571,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(view));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, view);
     return withCatalog(
         securityContext,
         prefix,
@@ -614,7 +613,7 @@ public class IcebergCatalogAdapter
                 .toList());
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(view));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, view);
     return withCatalog(
         securityContext,
         prefix,
@@ -665,7 +664,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     return withCatalog(
         securityContext,
         prefix,
@@ -685,7 +684,7 @@ public class IcebergCatalogAdapter
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table));
+    TableIdentifier tableIdentifier = TableIdentifier.of(ns, table);
     return withCatalog(
         securityContext,
         prefix,
diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogAdapter.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogAdapter.java
index e2c03c0053..30e31b3eea 100644
--- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogAdapter.java
+++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/PolicyCatalogAdapter.java
@@ -23,7 +23,6 @@ import jakarta.inject.Inject;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
 import org.apache.iceberg.catalog.Namespace;
-import org.apache.iceberg.rest.RESTUtil;
 import org.apache.polaris.core.auth.PolarisPrincipal;
 import org.apache.polaris.core.config.FeatureConfiguration;
 import org.apache.polaris.core.config.RealmConfig;
@@ -93,8 +92,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyType type =
-        policyType != null ? PolicyType.fromName(RESTUtil.decodeString(policyType)) : null;
+    PolicyType type = policyType != null ? PolicyType.fromName(policyType) : null;
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     ListPoliciesResponse response = handler.listPolicies(ns, type);
     return Response.ok(response).build();
@@ -109,7 +107,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyIdentifier identifier = new PolicyIdentifier(ns, RESTUtil.decodeString(policyName));
+    PolicyIdentifier identifier = new PolicyIdentifier(ns, policyName);
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     LoadPolicyResponse response = handler.loadPolicy(identifier);
     return Response.ok(response).build();
@@ -125,7 +123,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyIdentifier identifier = new PolicyIdentifier(ns, RESTUtil.decodeString(policyName));
+    PolicyIdentifier identifier = new PolicyIdentifier(ns, policyName);
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     LoadPolicyResponse response = handler.updatePolicy(identifier, updatePolicyRequest);
     return Response.ok(response).build();
@@ -141,7 +139,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyIdentifier identifier = new PolicyIdentifier(ns, RESTUtil.decodeString(policyName));
+    PolicyIdentifier identifier = new PolicyIdentifier(ns, policyName);
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     handler.dropPolicy(identifier, detachAll != null && detachAll);
     return Response.noContent().build();
@@ -157,7 +155,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyIdentifier identifier = new PolicyIdentifier(ns, RESTUtil.decodeString(policyName));
+    PolicyIdentifier identifier = new PolicyIdentifier(ns, policyName);
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     handler.attachPolicy(identifier, attachPolicyRequest);
     return Response.noContent().build();
@@ -173,7 +171,7 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
       SecurityContext securityContext) {
     Namespace ns =
         NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR);
-    PolicyIdentifier identifier = new PolicyIdentifier(ns, RESTUtil.decodeString(policyName));
+    PolicyIdentifier identifier = new PolicyIdentifier(ns, policyName);
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
     handler.detachPolicy(identifier, detachPolicyRequest);
     return Response.noContent().build();
@@ -193,11 +191,9 @@ public class PolicyCatalogAdapter implements PolarisCatalogPolicyApiService, Cat
         namespace != null
             ? NamespaceUtils.splitNamespace(namespace, NamespaceUtils.DEFAULT_NAMESPACE_SEPARATOR)
             : null;
-    String target = targetName != null ? RESTUtil.decodeString(targetName) : null;
-    PolicyType type =
-        policyType != null ? PolicyType.fromName(RESTUtil.decodeString(policyType)) : null;
+    PolicyType type = policyType != null ? PolicyType.fromName(policyType) : null;
     PolicyCatalogHandler handler = newHandler(securityContext, prefix);
-    GetApplicablePoliciesResponse response = handler.getApplicablePolicies(ns, target, type);
+    GetApplicablePoliciesResponse response = handler.getApplicablePolicies(ns, targetName, type);
     return Response.ok(response).build();
   }
 }