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();
}
}