From fb691255a868ddae4e79f8c32f496dd827343d9c Mon Sep 17 00:00:00 2001 From: brharrington Date: Wed, 8 Nov 2023 15:27:34 -0600 Subject: [PATCH] ipc: avoid exception for empty paths (#1092) Fix StringIndexOutOfBoundsException if sanitize is called with an empty path string. Also updates the logic for `/` to be consistent with an empty path string. Both will now get sanitized to `none` as tag values cannot be empty. --- .../com/netflix/spectator/ipc/http/PathSanitizer.java | 9 +++++---- .../netflix/spectator/ipc/http/PathSanitizerTest.java | 8 ++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/spectator-ext-ipc/src/main/java/com/netflix/spectator/ipc/http/PathSanitizer.java b/spectator-ext-ipc/src/main/java/com/netflix/spectator/ipc/http/PathSanitizer.java index 50cdac5c1..f1e839829 100644 --- a/spectator-ext-ipc/src/main/java/com/netflix/spectator/ipc/http/PathSanitizer.java +++ b/spectator-ext-ipc/src/main/java/com/netflix/spectator/ipc/http/PathSanitizer.java @@ -40,7 +40,7 @@ private PathSanitizer() { /** Returns a sanitized path string for use as an endpoint tag value. */ public static String sanitize(String path) { - return sanitizeSegments(removeParameters(path), Collections.emptySet()); + return sanitize(path, Collections.emptySet()); } /** @@ -55,7 +55,8 @@ public static String sanitize(String path) { * Sanitized path that can be used as an endpoint tag value. */ public static String sanitize(String path, Set allowed) { - return sanitizeSegments(removeParameters(path), allowed); + String tmp = sanitizeSegments(removeParameters(path), allowed); + return tmp.isEmpty() ? "none" : tmp; } private static String removeParameters(String path) { @@ -64,13 +65,13 @@ private static String removeParameters(String path) { private static String removeParameters(String path, char c) { int i = path.indexOf(c); - return i > 0 ? path.substring(0, i) : path; + return i >= 0 ? path.substring(0, i) : path; } private static String sanitizeSegments(String path, Set allowed) { StringBuilder builder = new StringBuilder(); int length = path.length(); - int pos = path.charAt(0) == '/' ? 1 : 0; + int pos = path.isEmpty() || path.charAt(0) != '/' ? 0 : 1; int segmentsAdded = 0; while (pos < length && segmentsAdded < 5) { diff --git a/spectator-ext-ipc/src/test/java/com/netflix/spectator/ipc/http/PathSanitizerTest.java b/spectator-ext-ipc/src/test/java/com/netflix/spectator/ipc/http/PathSanitizerTest.java index faf704262..92d0893f3 100644 --- a/spectator-ext-ipc/src/test/java/com/netflix/spectator/ipc/http/PathSanitizerTest.java +++ b/spectator-ext-ipc/src/test/java/com/netflix/spectator/ipc/http/PathSanitizerTest.java @@ -37,6 +37,14 @@ private String sanitize(String path) { return PathSanitizer.sanitize(path); } + @Test + public void emptyPath() { + Assertions.assertEquals("none", sanitize("/")); + Assertions.assertEquals("none", sanitize("")); + Assertions.assertEquals("none", sanitize("/?a=1")); + Assertions.assertEquals("none", sanitize("?a=1")); + } + @Test public void uuids() { String path = "/api/v1/foo/" + UUID.randomUUID();