jiangxt2 opened a new issue, #13189:
URL: https://github.com/apache/gravitino/issues/13189

   ### Version
   main branch
   
   ### Describe what's wrong
   `LancePropertiesUtils.getLanceStorageOptions()` accepts a property whose key 
is exactly `lance.storage.` and strips the prefix to an empty Lance 
storage-option key. The malformed key also passes Gravitino's generic property 
validation because it matches the declared prefix property entry, whose string 
decoder is identity; the validation does not require a non-empty suffix. An 
invalid option can therefore be passed deeper into Lance or retained in 
metadata, and any eventual failure is detached from the original input.
   
   ### Error message and/or stacktrace
   No exception or stacktrace is produced for the malformed key at the 
extraction boundary; it is silently accepted.
   
   ### How to reproduce
   **Minimal helper-level reproduction**
   1. Create a table property with the exact key `lance.storage.` and any 
value, for example `empty-key-value`.
   2. Add a normal option such as `lance.storage.endpoint=http://one`.
   3. Pass the properties to `LancePropertiesUtils.getLanceStorageOptions()`.
   4. Observe that the returned map is `{=empty-key-value, 
endpoint=http://one}` and that `containsKey("") == true` instead of the input 
being rejected.
   
   **Client-reachable REST path**
   1. Send a Lance REST create request with the query parameter 
`storage_options={"":"v"}`.
   2. Observe that Gravitino's `toTableProperties()` conversion produces the 
exact property key `lance.storage.` before the table operation receives it.
   
   Expected behavior: reject only the exact property key `lance.storage.` with 
an input-validation error before producing a Lance option with an empty name. 
Normal keys such as `lance.storage.endpoint` and arbitrary non-empty 
provider-specific keys such as `lance.storage.s3.custom_option` must remain 
supported.
   
   ### Additional context
   On the current main branch, ordinary create can pass the malformed option to 
dataset creation. Declare can persist the malformed table metadata and its 
response-side resolution does not reject the empty key, while register can 
persist the malformed property and return success because it bypasses that 
resolution. The same empty key is not rejected when existing metadata is later 
described, altered, or dropped on main, although downstream provider behavior 
may still vary.
   
   With an extraction-boundary fix that rejects the exact key, ordinary create 
fails before dataset creation or metadata persistence. Existing malformed 
metadata can then make describe or Lance alter fail, and a non-external drop 
can remove metadata before storage cleanup fails; these are consequences of 
applying the boundary fix to metadata that was already accepted.
   
   After this extraction-boundary fix, declare may persist metadata before the 
common response-side resolution rejects the key and return an error, while 
register still bypasses that resolution and may persist the malformed property 
and return success.
   
   This report focuses on rejecting the exact empty suffix at the extraction 
boundary. Pre-persistence validation in `toTableProperties()` and the relevant 
create/declare/register catalog and table input paths is outside this initial 
scope and can be tracked separately. Provider allowlists, whitespace semantics, 
and storage-property inheritance or precedence are also outside the scope. I am 
willing to prepare a focused fix for this issue, and feedback on the behavior 
and scope is welcome.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to