Skip to content

Fix bugs found during code audit across api, adminapi, functional, examples#1711

Draft
balamurugana wants to merge 2 commits into
minio:masterfrom
balamurugana:Fix-bugs-found-during-code-audit-across-api-adminapi-functional-examples
Draft

Fix bugs found during code audit across api, adminapi, functional, examples#1711
balamurugana wants to merge 2 commits into
minio:masterfrom
balamurugana:Fix-bugs-found-during-code-audit-across-api-adminapi-functional-examples

Conversation

@balamurugana

@balamurugana balamurugana commented Jun 27, 2026

Copy link
Copy Markdown
Member

api:

  • Compose/copy >5GiB: send per-part x-amz-copy-source-range (was loop-invariant)
  • Checksum.CRC64NVME.update: bound the slicing loop by len, not p.length
  • messages/Filter: keep And(String,Map) tags; "exactly one" via new Utils.xor
  • Http BaseUrl: ELB endpoints derive the real region (was "com")
  • messages/Checksum.headers(): emit x-amz-checksum-
  • PromptObjectArgs prompt setter; ListPartsArgs.Builder extends ObjectArgs.Builder
  • maxKeys() null-safe; Arrays.hashCode for array-backed args
  • downloadObject error propagation + temp cleanup; snowball/appendObject RAF close
  • uploadPartsParallelly buffer return/abort; executeAsync 304 return
  • credential providers: AwsConfig/MinioClientConfig/MinioEnvironment NPE -> clean
  • GetPresignedObjectUrlArgs expiry overflow; ObjectLockConfiguration duration();
    AccessControlPolicy null owner; ListenBucketNotificationArgs requires bucket;
    GetObjectAttributesArgs validation; LifecycleConfiguration via Utils.xor;
    VersioningConfiguration.excludeFolders() primitive; ReplicationConfiguration text

adminapi:

  • updateServiceAccount newStatus nullable (no silent disable)
  • Status.fromString null-guard; thread signing Credentials through execute()
  • getBucketQuota asLong(); Crypto.encrypt exact-multiple chunk; map getters
    return empty map when absent

functional:

  • PutObjectRunnable surfaces thread failures; notification tests assert;
    legal-hold tests fixed; stream/temp-file cleanup; TestUserAgent guards;
    MintLogger throws UncheckedIOException instead of blank log

examples:

  • close getObject/Response/progress streams (try-with-resources); fix
    GetObjectProgressBar/SelectObjectContent object names; real file size as object
    size; provider isSuccessful() check; placeholder credentials

Also add CLAUDE.md with build commands and architecture overview.

Signed-off-by: Bala.FA bala@minio.io

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability for downloads, multipart uploads, and progress tracking.
    • Fixed several cases where missing values could cause runtime errors in admin and object listing responses.
    • Corrected hashing and validation behavior for object-related requests.
    • Updated object download and upload examples to close streams safely and use accurate file sizes.
  • Chores

    • Updated build, CI, and wrapper tooling versions.
    • Added clearer repository guidance and tightened binary/line-ending handling.

Depends on #1709

Signed-off-by: Bala.FA <bala@minio.io>
@coderabbitai

coderabbitai Bot commented Jun 27, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c2666d79-6f19-41f0-af69-443a30e03898

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR updates build and wrapper tooling, adds repository guidance, changes admin and API parsing and validation behavior, adjusts async client download and upload control flow, and refreshes examples and functional tests.

Changes

Repository build and tooling

Layer / File(s) Summary
Build script updates
build.gradle
Plugin and dependency versions change, Java 8 bytecode targeting is enforced, a Java 25 toolchain is configured, Spotless is upgraded, signing blocks are rewritten, and generated source compilation is excluded in examples and functional code.
Workflow and wrapper execution
.github/workflows/gradle.yml, gradle/wrapper/gradle-wrapper.properties
The Java CI workflow adds Java 25 setup, changes the test setup condition, refreshes functional-test jar downloads and classpaths, and the wrapper distribution moves to Gradle 9.6.0 with retry settings.
Wrapper scripts
gradlew, gradlew.bat
The POSIX and Windows wrapper scripts drop CLASSPATH handling, invoke the wrapper jar with -jar, and revise startup and failure control flow.
Repository policy and guidance
.gitattributes, CLAUDE.md, spotbugs-filter.xml
LF normalization, binary file rules, repository guidance, and a SpotBugs suppression for IAOM_DO_NOT_INCREASE_METHOD_ACCESSIBILITY are added.

Admin API updates

Layer / File(s) Summary
Response guards and chunking
adminapi/src/main/java/io/minio/admin/Crypto.java, adminapi/src/main/java/io/minio/admin/GetDataUsageInfoResponse.java, adminapi/src/main/java/io/minio/admin/GetServerInfoResponse.java, adminapi/src/main/java/io/minio/admin/Status.java
Crypto.encrypt changes the final-chunk boundary, collection getters return empty maps for null backing fields, and Status.fromString treats null and empty input the same.
Request execution plumbing
adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
httpExecute and execute take explicit credentials, and user and service-account request paths pass those credentials through.
Service account and policy handling
adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
getBucketQuota parses the quota with asLong(), updateServiceAccount accepts a nullable Boolean newStatus, and attachDetachPolicy validates user and group with Utils.xor.

Core API contracts and helpers

Layer / File(s) Summary
Argument builders and defaults
api/src/main/java/io/minio/Utils.java, api/src/main/java/io/minio/PutObjectAPIBaseArgs.java, api/src/main/java/io/minio/GetObjectAttributesArgs.java, api/src/main/java/io/minio/GetPresignedObjectUrlArgs.java, api/src/main/java/io/minio/PromptObjectArgs.java, api/src/main/java/io/minio/ListObjectVersionsArgs.java, api/src/main/java/io/minio/ListObjectsV1Args.java, api/src/main/java/io/minio/ListObjectsV2Args.java, api/src/main/java/io/minio/ListPartsArgs.java, api/src/main/java/io/minio/ListenBucketNotificationArgs.java, api/src/main/java/io/minio/UploadSnowballObjectsArgs.java, api/src/main/java/io/minio/Http.java
Utils.xor is added and used in builder validation, several builders add range checks or null-safe defaults, PromptObjectArgs renames its fluent setter, UploadSnowballObjectsArgs initializes objectName in its constructor, and Http adjusts AWS host parsing.
Hashing and stream handling
api/src/main/java/io/minio/AppendObjectArgs.java, api/src/main/java/io/minio/CompleteMultipartUploadArgs.java, api/src/main/java/io/minio/PutObjectAPIBaseArgs.java, api/src/main/java/io/minio/PutObjectArgs.java, api/src/main/java/io/minio/BaseS3Client.java, api/src/main/java/io/minio/Checksum.java, api/src/main/java/io/minio/PartReader.java
Array-backed hashes use content hashes, checksum processing uses the requested slice bounds, BaseS3Client changes its HTTP 304 error check, and PartReader keeps the formatting-only loop change.
Credentials and config parsing
api/src/main/java/io/minio/credentials/AwsConfigProvider.java, api/src/main/java/io/minio/credentials/MinioClientConfigProvider.java, api/src/main/java/io/minio/credentials/MinioEnvironmentProvider.java, api/src/main/java/io/minio/errors/MinioException.java
INI parsing skips entries before the first section, config alias lookup and environment credentials handle nulls, and MinioException reformats its throws clause.
Message guards and headers
api/src/main/java/io/minio/messages/AccessControlPolicy.java, api/src/main/java/io/minio/messages/Checksum.java, api/src/main/java/io/minio/messages/Filter.java, api/src/main/java/io/minio/messages/LifecycleConfiguration.java, api/src/main/java/io/minio/messages/ObjectLockConfiguration.java, api/src/main/java/io/minio/messages/ReplicationConfiguration.java, api/src/main/java/io/minio/messages/VersioningConfiguration.java
ACL detection adds a null guard, checksum headers use the corrected name, Filter validation switches to Utils.xor and Filter.And builds tags in a local list, retention accessors return 0 on null, and versioning and replication accessors/messages change.

Async client, examples, and functional tests

Layer / File(s) Summary
Download cleanup and completion
api/src/main/java/io/minio/MinioAsyncClient.java
downloadObject tracks a temp file path, deletes partial downloads in finally, and rethrows MinioException as CompletionException.
Multipart queue and file lifecycle
api/src/main/java/io/minio/MinioAsyncClient.java
Multipart copy uses per-part headers, worker buffers are returned in finally, queue offers retry via offerUntilDoneOrError, and staged upload and append flows close RandomAccessFile explicitly.
Object and progress examples
examples/GetObject.java, examples/GetObjectProgressBar.java, examples/GetPartialObject.java, examples/GetPresignedPostFormData.java, examples/ProgressStream.java, examples/PutObjectProgressBar.java, examples/PutObjectUiProgressBar.java, examples/SelectObjectContent.java
The object download, progress-bar, partial-read, presigned-post, progress-stream, and select-object-content examples switch to try-with-resources or corrected progress/accounting logic.
Credential-provider examples
examples/MinioClientWithAssumeRoleProvider.java, examples/MinioClientWithClientGrantsProvider.java, examples/MinioClientWithWebIdentityProvider.java
The AssumeRole example uses placeholder values, and the client-grants and web-identity examples fail on unsuccessful token responses.
Functional support and threaded putObject
functional/MintLogger.java, functional/PutObjectRunnable.java, functional/TestMinioClient.java
MintLogger throws UncheckedIOException on serialization failure, PutObjectRunnable records exceptions, and the threaded putObject, download cleanup, presigned upload, copy-object, and compose setup paths in TestMinioClient use those results.
Functional assertions and user-agent parsing
functional/TestMinioClient.java, functional/TestUserAgent.java
Legal-hold, bucket-notification, select-object-content, and User-Agent checks change their assertions, failure handling, and parsing guards.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I hopped through builds with twitching nose,
and nibbled wrappers, row by row.
I found some nulls, then fixed the flow,
I bopped the tests to make them glow,
Hooray! said I, “the carrots know.” 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.73% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: bug fixes discovered during code audit across api, adminapi, functional, and examples.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@balamurugana balamurugana changed the title Fix bugs found during code audit across api adminapi functional examples Fix bugs found during code audit across api, adminapi, functional, examples Jun 27, 2026
@balamurugana balamurugana marked this pull request as draft June 27, 2026 07:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
api/src/main/java/io/minio/PromptObjectArgs.java (1)

59-63: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep offset(String) as a delegating alias Renaming this public builder method breaks existing PromptObjectArgs consumers; preserve the old name and forward it to prompt(String) instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api/src/main/java/io/minio/PromptObjectArgs.java` around lines 59 - 63, The
public builder API in PromptObjectArgs.Builder should preserve backward
compatibility by keeping offset(String) as a delegating alias instead of
replacing it with prompt(String). Update the Builder methods so offset(String)
forwards to prompt(String), and keep prompt(String) as the shared implementation
that validates and sets the prompt field, ensuring existing consumers of
offset(String) continue to work.
functional/TestMinioClient.java (1)

2651-2658: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Assert the notification filter too.

The expected config includes new NotificationConfiguration.Filter("images", "pg"), but the mismatch check only validates queue ARN and event. A broken filter round-trip still passes this test.

Proposed full-config comparison
         NotificationConfiguration config =
             client.getBucketNotification(
                 GetBucketNotificationArgs.builder().bucket(bucketName).build());
 
-        if (config.queueConfigurations().size() != 1
-            || !sqsArn.equals(config.queueConfigurations().get(0).queue())
-            || config.queueConfigurations().get(0).events().size() != 1
-            || !EventType.OBJECT_CREATED_PUT
-                .toString()
-                .equals(config.queueConfigurations().get(0).events().get(0))) {
+        String expectedXml = Xml.marshal(expectedConfig);
+        String actualXml = Xml.marshal(config);
+        if (!expectedXml.equals(actualXml)) {
           throw new Exception(
-              "config: expected: " + Xml.marshal(expectedConfig) + ", got: " + Xml.marshal(config));
+              "config: expected: " + expectedXml + ", got: " + actualXml);
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@functional/TestMinioClient.java` around lines 2651 - 2658, The notification
configuration check only validates the queue ARN and event in the relevant test,
so a broken filter round-trip can still pass. Update the assertion logic around
the config queue validation to also compare the filter on the queue
configuration against the expected NotificationConfiguration.Filter("images",
"pg"), using the existing config.queueConfigurations().get(0) and expectedConfig
values to verify the full notification payload.
adminapi/src/main/java/io/minio/admin/MinioAdminClient.java (1)

719-745: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Preserve the primitive updateServiceAccount overload. Changing this public parameter from boolean to Boolean breaks binary compatibility for existing callers and can trigger NoSuchMethodError. Add a boolean overload that delegates to the nullable version.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adminapi/src/main/java/io/minio/admin/MinioAdminClient.java` around lines 719
- 745, The public updateServiceAccount API has lost its primitive boolean
signature, which breaks existing callers and can cause NoSuchMethodError. In
MinioAdminClient, keep the nullable Boolean-based implementation but add a
boolean overload for updateServiceAccount that delegates to the existing method,
preserving binary compatibility while keeping the current logic centralized.
gradlew.bat (1)

54-82: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Terminate the batch script on failure. "%COMSPEC%" /c exit 1 only exits the child cmd, so the error paths can continue into :findJavaFromJavaHome / :execute. Replace them with exit /b 1, and use exit /b %ERRORLEVEL% in :exitWithErrorLevel.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gradlew.bat` around lines 54 - 82, The batch error handling in gradlew.bat
does not stop the parent script, so failure paths can fall through into
:findJavaFromJavaHome and :execute. Update the early failure exits and the
invalid JAVA_HOME branch to terminate the script with exit /b 1, and change
:exitWithErrorLevel to return the current error code with exit /b %ERRORLEVEL%.
Use the existing labels :findJavaFromJavaHome, :execute, and :exitWithErrorLevel
to locate the affected paths.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@adminapi/src/main/java/io/minio/admin/MinioAdminClient.java`:
- Around line 473-480: The quota parsing in MinioAdminClient should reject
non-numeric JSON instead of coercing it to 0. In the response-handling code that
streams the parsed map and extracts the "quota" entry, check that the JsonNode
is actually numeric before converting it, and throw an error if it is missing or
not a number rather than relying on asLong(). Keep the existing quota lookup
flow, but update the parsing logic to treat malformed quota values as failures.

In `@functional/TestMinioClient.java`:
- Around line 965-967: In TestMinioClient, the cleanup in the test teardown
currently deletes the local file before calling client.removeObject, so a local
deletion failure can prevent remote object cleanup. Update the teardown logic
around args.filename(), args.bucket(), and args.object() to ensure
client.removeObject(RemoveObjectArgs.builder()...) runs first or is guaranteed
via a nested finally, then perform Files.deleteIfExists afterward so both
cleanup steps are always attempted.

In `@gradle/wrapper/gradle-wrapper.properties`:
- Around line 5-6: The Gradle wrapper configuration currently disables download
retries by setting retries to zero, which makes bootstrap fail on any transient
network issue. Update the wrapper properties to use a small non-zero retry count
so the retryBackOffMs setting in gradle-wrapper.properties actually takes effect
and can absorb flaky distribution downloads.

---

Outside diff comments:
In `@adminapi/src/main/java/io/minio/admin/MinioAdminClient.java`:
- Around line 719-745: The public updateServiceAccount API has lost its
primitive boolean signature, which breaks existing callers and can cause
NoSuchMethodError. In MinioAdminClient, keep the nullable Boolean-based
implementation but add a boolean overload for updateServiceAccount that
delegates to the existing method, preserving binary compatibility while keeping
the current logic centralized.

In `@api/src/main/java/io/minio/PromptObjectArgs.java`:
- Around line 59-63: The public builder API in PromptObjectArgs.Builder should
preserve backward compatibility by keeping offset(String) as a delegating alias
instead of replacing it with prompt(String). Update the Builder methods so
offset(String) forwards to prompt(String), and keep prompt(String) as the shared
implementation that validates and sets the prompt field, ensuring existing
consumers of offset(String) continue to work.

In `@functional/TestMinioClient.java`:
- Around line 2651-2658: The notification configuration check only validates the
queue ARN and event in the relevant test, so a broken filter round-trip can
still pass. Update the assertion logic around the config queue validation to
also compare the filter on the queue configuration against the expected
NotificationConfiguration.Filter("images", "pg"), using the existing
config.queueConfigurations().get(0) and expectedConfig values to verify the full
notification payload.

In `@gradlew.bat`:
- Around line 54-82: The batch error handling in gradlew.bat does not stop the
parent script, so failure paths can fall through into :findJavaFromJavaHome and
:execute. Update the early failure exits and the invalid JAVA_HOME branch to
terminate the script with exit /b 1, and change :exitWithErrorLevel to return
the current error code with exit /b %ERRORLEVEL%. Use the existing labels
:findJavaFromJavaHome, :execute, and :exitWithErrorLevel to locate the affected
paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: caa38ccf-7cc5-4b2e-adbd-e7c3255befa3

📥 Commits

Reviewing files that changed from the base of the PR and between 942e2e5 and 43737fa.

⛔ Files ignored due to path filters (1)
  • gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (58)
  • .gitattributes
  • .github/workflows/gradle.yml
  • CLAUDE.md
  • adminapi/src/main/java/io/minio/admin/Crypto.java
  • adminapi/src/main/java/io/minio/admin/GetDataUsageInfoResponse.java
  • adminapi/src/main/java/io/minio/admin/GetServerInfoResponse.java
  • adminapi/src/main/java/io/minio/admin/MinioAdminClient.java
  • adminapi/src/main/java/io/minio/admin/Status.java
  • api/src/main/java/io/minio/AppendObjectArgs.java
  • api/src/main/java/io/minio/BaseS3Client.java
  • api/src/main/java/io/minio/Checksum.java
  • api/src/main/java/io/minio/CompleteMultipartUploadArgs.java
  • api/src/main/java/io/minio/GetObjectAttributesArgs.java
  • api/src/main/java/io/minio/GetPresignedObjectUrlArgs.java
  • api/src/main/java/io/minio/Http.java
  • api/src/main/java/io/minio/ListObjectVersionsArgs.java
  • api/src/main/java/io/minio/ListObjectsV1Args.java
  • api/src/main/java/io/minio/ListObjectsV2Args.java
  • api/src/main/java/io/minio/ListPartsArgs.java
  • api/src/main/java/io/minio/ListenBucketNotificationArgs.java
  • api/src/main/java/io/minio/MinioAsyncClient.java
  • api/src/main/java/io/minio/PartReader.java
  • api/src/main/java/io/minio/PromptObjectArgs.java
  • api/src/main/java/io/minio/PutObjectAPIBaseArgs.java
  • api/src/main/java/io/minio/PutObjectArgs.java
  • api/src/main/java/io/minio/UploadSnowballObjectsArgs.java
  • api/src/main/java/io/minio/Utils.java
  • api/src/main/java/io/minio/credentials/AwsConfigProvider.java
  • api/src/main/java/io/minio/credentials/MinioClientConfigProvider.java
  • api/src/main/java/io/minio/credentials/MinioEnvironmentProvider.java
  • api/src/main/java/io/minio/errors/MinioException.java
  • api/src/main/java/io/minio/messages/AccessControlPolicy.java
  • api/src/main/java/io/minio/messages/Checksum.java
  • api/src/main/java/io/minio/messages/Filter.java
  • api/src/main/java/io/minio/messages/LifecycleConfiguration.java
  • api/src/main/java/io/minio/messages/ObjectLockConfiguration.java
  • api/src/main/java/io/minio/messages/ReplicationConfiguration.java
  • api/src/main/java/io/minio/messages/VersioningConfiguration.java
  • build.gradle
  • examples/GetObject.java
  • examples/GetObjectProgressBar.java
  • examples/GetPartialObject.java
  • examples/GetPresignedPostFormData.java
  • examples/MinioClientWithAssumeRoleProvider.java
  • examples/MinioClientWithClientGrantsProvider.java
  • examples/MinioClientWithWebIdentityProvider.java
  • examples/ProgressStream.java
  • examples/PutObjectProgressBar.java
  • examples/PutObjectUiProgressBar.java
  • examples/SelectObjectContent.java
  • functional/MintLogger.java
  • functional/PutObjectRunnable.java
  • functional/TestMinioClient.java
  • functional/TestUserAgent.java
  • gradle/wrapper/gradle-wrapper.properties
  • gradlew
  • gradlew.bat
  • spotbugs-filter.xml

Comment on lines +473 to +480
return OBJECT_MAPPER
.<Map<String, JsonNode>>readValue(response.body().bytes(), mapType)
.entrySet()
.stream()
.filter(entry -> "quota".equals(entry.getKey()))
.findFirst()
.map(entry -> Long.valueOf(entry.getValue().toString()))
.orElseThrow(() -> new IllegalArgumentException("found not quota"));
.map(entry -> entry.getValue().asLong())
.orElseThrow(() -> new IllegalArgumentException("quota not found in response"));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the surrounding method and relevant imports in the target file.
file="adminapi/src/main/java/io/minio/admin/MinioAdminClient.java"
wc -l "$file"
sed -n '430,520p' "$file"

# Find any other quota parsing or validation logic in the repository.
rg -n "quota not found in response|asLong\(\)|quota" adminapi/src/main/java/io/minio/admin -S

Repository: minio/minio-java

Length of output: 4603


Parse quota as a number before returning it.

asLong() coerces non-numeric JSON to 0, so a malformed response is indistinguishable from a cleared quota. Treat a non-numeric quota as an error instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@adminapi/src/main/java/io/minio/admin/MinioAdminClient.java` around lines 473
- 480, The quota parsing in MinioAdminClient should reject non-numeric JSON
instead of coercing it to 0. In the response-handling code that streams the
parsed map and extracts the "quota" entry, check that the JsonNode is actually
numeric before converting it, and throw an error if it is missing or not a
number rather than relying on asLong(). Keep the existing quota lookup flow, but
update the parsing logic to treat malformed quota values as failures.

Comment on lines +965 to 967
Files.deleteIfExists(Paths.get(args.filename()));
client.removeObject(
RemoveObjectArgs.builder().bucket(args.bucket()).object(args.object()).build());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Ensure remote cleanup still runs if local file deletion fails.

Files.deleteIfExists(...) can throw before client.removeObject(...), leaving the uploaded object behind and potentially breaking later bucket cleanup. Move remote cleanup before local deletion with a nested finally so both cleanup actions are attempted.

As per coding guidelines, functional/**/*.java tests hit a real S3/MinIO server, so cleanup should not be skipped.

Proposed cleanup ordering fix
     } catch (Exception e) {
       handleException(methodName, testTags, startTime, e);
     } finally {
-      Files.deleteIfExists(Paths.get(args.filename()));
-      client.removeObject(
-          RemoveObjectArgs.builder().bucket(args.bucket()).object(args.object()).build());
+      try {
+        client.removeObject(
+            RemoveObjectArgs.builder().bucket(args.bucket()).object(args.object()).build());
+      } finally {
+        Files.deleteIfExists(Paths.get(args.filename()));
+      }
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Files.deleteIfExists(Paths.get(args.filename()));
client.removeObject(
RemoveObjectArgs.builder().bucket(args.bucket()).object(args.object()).build());
try {
client.removeObject(
RemoveObjectArgs.builder().bucket(args.bucket()).object(args.object()).build());
} finally {
Files.deleteIfExists(Paths.get(args.filename()));
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@functional/TestMinioClient.java` around lines 965 - 967, In TestMinioClient,
the cleanup in the test teardown currently deletes the local file before calling
client.removeObject, so a local deletion failure can prevent remote object
cleanup. Update the teardown logic around args.filename(), args.bucket(), and
args.object() to ensure client.removeObject(RemoveObjectArgs.builder()...) runs
first or is guaranteed via a nested finally, then perform Files.deleteIfExists
afterward so both cleanup steps are always attempted.

Source: Coding guidelines

Comment on lines +5 to +6
retries=0
retryBackOffMs=500

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

retries=0 disables Gradle wrapper download retries.

With retries=0, a single transient network failure while fetching the distribution will fail the wrapper bootstrap (and CI) with no retry, despite retryBackOffMs=500 being set (it has no effect at 0 retries). Consider a small non-zero value to absorb flaky downloads.

🔧 Suggested change
-retries=0
+retries=3
 retryBackOffMs=500
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
retries=0
retryBackOffMs=500
retries=3
retryBackOffMs=500
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@gradle/wrapper/gradle-wrapper.properties` around lines 5 - 6, The Gradle
wrapper configuration currently disables download retries by setting retries to
zero, which makes bootstrap fail on any transient network issue. Update the
wrapper properties to use a small non-zero retry count so the retryBackOffMs
setting in gradle-wrapper.properties actually takes effect and can absorb flaky
distribution downloads.

@balamurugana balamurugana force-pushed the Fix-bugs-found-during-code-audit-across-api-adminapi-functional-examples branch 12 times, most recently from bbdbf8e to c61bcbb Compare June 27, 2026 14:55
…amples

api:
- Compose/copy >5GiB: send per-part x-amz-copy-source-range (was loop-invariant)
- Checksum.CRC64NVME.update: bound the slicing loop by len, not p.length
- messages/Filter: keep And(String,Map) tags; "exactly one" via new Utils.xor
- Http BaseUrl: ELB endpoints derive the real region (was "com")
- messages/Checksum.headers(): emit x-amz-checksum-<algo>
- PromptObjectArgs prompt setter; ListPartsArgs.Builder extends ObjectArgs.Builder
- maxKeys() null-safe; Arrays.hashCode for array-backed args
- downloadObject error propagation + temp cleanup; snowball/appendObject RAF close
- uploadPartsParallelly buffer return/abort; executeAsync 304 return
- credential providers: AwsConfig/MinioClientConfig/MinioEnvironment NPE -> clean
- GetPresignedObjectUrlArgs expiry overflow; ObjectLockConfiguration duration();
  AccessControlPolicy null owner; ListenBucketNotificationArgs requires bucket;
  GetObjectAttributesArgs validation; LifecycleConfiguration via Utils.xor;
  VersioningConfiguration.excludeFolders() primitive; ReplicationConfiguration text

adminapi:
- updateServiceAccount newStatus nullable (no silent disable)
- Status.fromString null-guard; thread signing Credentials through execute()
- getBucketQuota asLong(); Crypto.encrypt exact-multiple chunk; map getters
  return empty map when absent

functional:
- PutObjectRunnable surfaces thread failures; notification tests assert;
  legal-hold tests fixed; stream/temp-file cleanup; TestUserAgent guards;
  MintLogger throws UncheckedIOException instead of blank log

examples:
- close getObject/Response/progress streams (try-with-resources); fix
  GetObjectProgressBar/SelectObjectContent object names; real file size as object
  size; provider isSuccessful() check; placeholder credentials

Also add CLAUDE.md with build commands and architecture overview.

Signed-off-by: Bala.FA <bala@minio.io>
@balamurugana balamurugana force-pushed the Fix-bugs-found-during-code-audit-across-api-adminapi-functional-examples branch from c61bcbb to f29cd3e Compare June 29, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant