From 80f34d11a2d67224a705058a224618e5069c3da8 Mon Sep 17 00:00:00 2001 From: Wes Tarle Date: Mon, 15 Jun 2026 12:26:01 +0000 Subject: [PATCH 1/2] fix(auth): handle missing APPDATA on Windows gracefully Other languages (such as Python and Node.js) handle missing HOME or APPDATA directories by falling back gracefully or failing with a structured Error/Exception. This change brings Java into parity by ensuring an orderly IOException is thrown instead of an opaque NullPointerException when APPDATA is null. Fixes #12565 --- .../com/google/auth/oauth2/GoogleAuthUtils.java | 3 ++- .../oauth2/DefaultCredentialsProviderTest.java | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java index d82548a082fd..9524ec8e82ba 100644 --- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java +++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java @@ -70,7 +70,8 @@ static final File getWellKnownCredentialsFile(DefaultCredentialsProvider provide if (envPath != null) { cloudConfigPath = new File(envPath); } else if (provider.getOsName().indexOf("windows") >= 0) { - File appDataPath = new File(provider.getEnv("APPDATA")); + String appData = provider.getEnv("APPDATA"); + File appDataPath = new File(appData == null ? "" : appData); cloudConfigPath = new File(appDataPath, provider.CLOUDSDK_CONFIG_DIRECTORY); } else { File configPath = new File(provider.getProperty("user.home", ""), ".config"); diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java index d0447871b01a..60c8d34c9af6 100644 --- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java +++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java @@ -115,6 +115,21 @@ void getDefaultCredentials_noCredentials_throws() { assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message); } + @Test + void getDefaultCredentials_windowsMissingAppData_throwsOrFallback() { + // When APPDATA is unset on Windows, the ADC resolution should fail gracefully + // with a structured missing credentials exception, rather than crashing with an NPE. + // This matches the expected behavior seen in Node.js and Python implementations. + MockHttpTransportFactory transportFactory = new MockHttpTransportFactory(); + TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider(); + testProvider.setProperty("os.name", "windows"); + testProvider.setEnv("APPDATA", null); + + IOException e = + assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory)); + assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, e.getMessage()); + } + @Test void getDefaultCredentials_noCredentialsSandbox_throwsNonSecurity() { MockHttpTransportFactory transportFactory = new MockHttpTransportFactory(); From 4330ac34edcef6233b6c5c9dc97ffc9e52e94fc9 Mon Sep 17 00:00:00 2001 From: Wes Tarle Date: Mon, 15 Jun 2026 11:34:28 -0400 Subject: [PATCH 2/2] Update google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../java/com/google/auth/oauth2/GoogleAuthUtils.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java index 9524ec8e82ba..ac1da958cbca 100644 --- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java +++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GoogleAuthUtils.java @@ -71,7 +71,10 @@ static final File getWellKnownCredentialsFile(DefaultCredentialsProvider provide cloudConfigPath = new File(envPath); } else if (provider.getOsName().indexOf("windows") >= 0) { String appData = provider.getEnv("APPDATA"); - File appDataPath = new File(appData == null ? "" : appData); + if (appData == null) { + return null; + } + File appDataPath = new File(appData); cloudConfigPath = new File(appDataPath, provider.CLOUDSDK_CONFIG_DIRECTORY); } else { File configPath = new File(provider.getProperty("user.home", ""), ".config");