Skip to content

[MINOR][CORE] Document the JavaUtils.checkArgument format-string contract and fix a concatenating caller - #58740

Open
david-mollitor-db wants to merge 1 commit into
apache:masterfrom
david-mollitor-db:javautils-checkargument-format
Open

[MINOR][CORE] Document the JavaUtils.checkArgument format-string contract and fix a concatenating caller#58740
david-mollitor-db wants to merge 1 commit into
apache:masterfrom
david-mollitor-db:javautils-checkargument-format

Conversation

@david-mollitor-db

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

JavaUtils.checkArgument and JavaUtils.checkState build their failure message with
String.format(msg, args), so msg is a format string and callers are meant to pass runtime
values as trailing args (e.g. checkArgument(cond, "bad key: %s", key)). This was not documented,
and one caller concatenated the value into the message instead. This PR:

  • Expands the checkArgument / checkState JavaDoc to describe the String.format contract and
    warn against interpolating values into msg, showing the correct %s idiom.

  • Fixes the concatenating caller in RemoteBlockPushResolver.validateAndGetAppShuffleInfo:

    // before
    JavaUtils.checkArgument(appShuffleInfo != null,
      "application " + appId + " is not registered or NM was restarted.");
    // after
    JavaUtils.checkArgument(appShuffleInfo != null,
      "application %s is not registered or NM was restarted.", appId);

Why are the changes needed?

Concatenating a value into msg is unsafe. On the failure path String.format treats the
already-interpolated text as the format string, so a stray % in the value (a percent-encoded
token, a Windows path such as %TEMP%, a SQL LIKE pattern, a number like "50%") makes it throw
an IllegalFormatException that replaces the intended IllegalArgumentException and hides the real
reason the check failed. It also builds the message eagerly on every call, including the common
success path where it is immediately discarded. Documenting the contract and correcting the one
concatenating caller prevents this.

Does this PR introduce any user-facing change?

No. The message produced by the corrected caller is identical (%s is substituted with appId),
and the remaining changes are documentation only.

How was this patch tested?

Existing RemoteBlockPushResolverSuite passes (46 tests; the two tests that assert the
"application ... is not registered" message still hold, since the produced text is unchanged).
Checkstyle is clean on both common-utils-java and network-shuffle.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Opus 4.8

This pull request and its description were written by Isaac.

…ract and fix a concatenating caller

`JavaUtils.checkArgument`/`checkState` build the failure message with
`String.format(msg, args)`, so `msg` is a format string and callers are meant
to pass runtime values as trailing `args` (e.g. `"bad key: %s", key`). The
JavaDoc did not say this, and at least one caller concatenated the value into
the message instead:

    JavaUtils.checkArgument(appShuffleInfo != null,
      "application " + appId + " is not registered or NM was restarted.");

Concatenating is unsafe: on the failure path `String.format` treats the
already-interpolated text as the format string, so a stray `%` in the value
(a percent-encoded token, a Windows path like `%TEMP%`, a `LIKE` pattern, a
number such as "50%") makes it throw an `IllegalFormatException` that replaces
the intended `IllegalArgumentException` and hides the real reason the check
failed. It also builds the message eagerly on every call, including the common
success path.

This change:

  - Expands the `checkArgument`/`checkState` JavaDoc to describe the
    `String.format` contract and warn against interpolating values into `msg`,
    with the correct `%s` idiom.
  - Converts the `RemoteBlockPushResolver.validateAndGetAppShuffleInfo` caller
    to pass `appId` as a format argument. The produced message is unchanged.

Co-authored-by: Isaac <no-reply@databricks.com>
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