minio-java icon indicating copy to clipboard operation
minio-java copied to clipboard

GetObjectTags parses empty string as null

Open simonhir opened this issue 8 months ago • 2 comments

Problem

In S3 tags with empty values are allowed but can't be null. The getObjectTags unmarshals the empty tag value to null instead of an empty string. If the returned tags are then e.g. reused for setObjectTags, the validation in the Tags constructor throws a NullPointerException while checking the key length.

java.lang.NullPointerException: Cannot invoke "String.length()" because "value" is null
    at io.minio.messages.Tags.<init>(Tags.java:85)
    at io.minio.messages.Tags.newObjectTags(Tags.java:100)
    at io.minio.SetObjectTagsArgs$Builder.lambda$tags$0(SetObjectTagsArgs.java:50)
    at io.minio.BaseArgs$Builder.lambda$build$4(BaseArgs.java:148)
    at java.util.ArrayList.forEach(ArrayList.java:1596)
    at io.minio.BaseArgs$Builder.build(BaseArgs.java:148)

One could discuss whether getObjectTags behaves validly here, but in my opinion it is a normal use case that you want to add a tag to the existing ones and therefore also treat an empty string as such.

Trace

---------START-HTTP---------
GET /test-bucket/test.pdf?tagging= HTTP/1.1
Host: localhost:9000
Accept-Encoding: identity
User-Agent: MinIO (Windows 10; amd64) minio-java/8.5.17
Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg==
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20250407T110505Z
Authorization: 

HTTP/1.1 200
Accept-Ranges: bytes
Content-Length: 487
Content-Type: application/xml
Server: MinIO
Strict-Transport-Security: max-age=31536000; includeSubDomains
Vary: Origin
Vary: Accept-Encoding
X-Amz-Id-2: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8
X-Amz-Request-Id: 183404805CAC5634
X-Content-Type-Options: nosniff
X-Xss-Protection: 1; mode=block
Date: Mon, 07 Apr 2025 11:05:05 GMT

<?xml version="1.0" encoding="UTF-8"?>
<Tagging><TagSet><Tag><Key>testKey</Key><Value></Value></Tag></TagSet></Tagging>
----------END-HTTP----------

leads to {testKey=null} instead of {testKey=""}

simonhir avatar Apr 07 '25 11:04 simonhir

Feel free to send a fix

balamurugana avatar Apr 07 '25 11:04 balamurugana

I looked a bit into it and and discovered that the used com.carrotsearch.thirdparty:simple-xml-safe:2.7.1 is no longer maintained. See https://github.com/carrotsearch/simplexml-safe As in my opinion it's more a "bug" of the XML lib how null is handled and there is no documentation available (as far as i saw), I wondered if it might be a good idea to switch to jackson-dataformat-xml as Jackson is already included and after a quick look I think that should handle only xsi:nil as null. @balamurugana what do you think? If yes i would try to replace it.

simonhir avatar Apr 09 '25 06:04 simonhir

Fixed by https://github.com/minio/minio-java/pull/1621

balamurugana avatar Jul 21 '25 17:07 balamurugana