|
16 | 16 |
|
17 | 17 | package org.springframework.boot.actuate.autoconfigure.opentelemetry;
|
18 | 18 |
|
19 |
| -import java.io.ByteArrayOutputStream; |
20 | 19 | import java.nio.charset.StandardCharsets;
|
21 | 20 | import java.util.Collections;
|
| 21 | +import java.util.HexFormat; |
22 | 22 | import java.util.LinkedHashMap;
|
23 | 23 | import java.util.Map;
|
24 | 24 | import java.util.function.BiConsumer;
|
|
43 | 43 | */
|
44 | 44 | public final class OpenTelemetryResourceAttributes {
|
45 | 45 |
|
| 46 | + private static final HexFormat HEX_FORMAT = HexFormat.of(); |
| 47 | + |
46 | 48 | /**
|
47 | 49 | * Default value for service name if {@code service.name} is not set.
|
48 | 50 | */
|
@@ -153,43 +155,25 @@ private String getEnv(String name) {
|
153 | 155 | return this.getEnv.apply(name);
|
154 | 156 | }
|
155 | 157 |
|
156 |
| - /** |
157 |
| - * Decodes a percent-encoded string. Converts sequences like '%HH' (where HH |
158 |
| - * represents hexadecimal digits) back into their literal representations. |
159 |
| - * <p> |
160 |
| - * Inspired by {@code org.apache.commons.codec.net.PercentCodec}. |
161 |
| - * @param value value to decode |
162 |
| - * @return the decoded string |
163 |
| - */ |
164 | 158 | private static String decode(String value) {
|
165 | 159 | if (value.indexOf('%') < 0) {
|
166 | 160 | return value;
|
167 | 161 | }
|
168 |
| - byte[] bytes = value.getBytes(StandardCharsets.UTF_8); |
169 |
| - ByteArrayOutputStream bos = new ByteArrayOutputStream(bytes.length); |
170 |
| - for (int i = 0; i < bytes.length; i++) { |
171 |
| - byte b = bytes[i]; |
172 |
| - if (b != '%') { |
173 |
| - bos.write(b); |
| 162 | + int length = value.length(); |
| 163 | + StringBuilder result = new StringBuilder(length); |
| 164 | + for (int i = 0; i < length; i++) { |
| 165 | + char ch = value.charAt(i); |
| 166 | + if (ch != '%') { |
| 167 | + result.append(ch); |
174 | 168 | continue;
|
175 | 169 | }
|
176 |
| - int u = decodeHex(bytes, i + 1); |
177 |
| - int l = decodeHex(bytes, i + 2); |
178 |
| - if (u >= 0 && l >= 0) { |
179 |
| - bos.write((u << 4) + l); |
180 |
| - } |
181 |
| - else { |
182 |
| - throw new IllegalArgumentException( |
183 |
| - "Failed to decode percent-encoded characters at index %d in the value: '%s'".formatted(i, |
184 |
| - value)); |
| 170 | + if (i + 2 >= length) { |
| 171 | + throw new IllegalArgumentException("Invalid encoded sequence \"%s\"".formatted(value.substring(i))); |
185 | 172 | }
|
| 173 | + result.append(new String(HEX_FORMAT.parseHex(value, i + 1, i + 3), StandardCharsets.UTF_8)); |
186 | 174 | i += 2;
|
187 | 175 | }
|
188 |
| - return bos.toString(StandardCharsets.UTF_8); |
189 |
| - } |
190 |
| - |
191 |
| - private static int decodeHex(byte[] bytes, int index) { |
192 |
| - return (index < bytes.length) ? Character.digit(bytes[index], 16) : -1; |
| 176 | + return result.toString(); |
193 | 177 | }
|
194 | 178 |
|
195 | 179 | }
|
0 commit comments