Skip to content

Commit 0de2fc2

Browse files
authored
Merge pull request #421 from Microsoft/dhdoshi/sanitizeJSON
Merge Dhdoshi/sanitize json into master
2 parents 46fc0e4 + f33c220 commit 0de2fc2

File tree

4 files changed

+108
-7
lines changed

4 files changed

+108
-7
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# CHANGELOG
22

33
## Version 1.0.10
4+
- Fixed issue #403 (Exceeding property length invalidates custom event)
5+
- Fixed issue #401 (Custom key and property sanitized)
6+
- Fixed Request Telemetry Sending bug with new schema.
47
- Fixed reliability issue with Jedis client dependency collector
58
- Fixed Request Telemetry Sending bug with new schema
69
- Schema updated to the latest version. Changes in internal namespace `core/src/main/java/com/microsoft/applicationinsights/internal/schemav2`.

core/src/main/java/com/microsoft/applicationinsights/telemetry/JsonTelemetryDataSerializer.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,16 @@
2121

2222
package com.microsoft.applicationinsights.telemetry;
2323

24+
import com.google.common.base.Strings;
25+
import com.microsoft.applicationinsights.internal.schemav2.DataPointType;
26+
import com.microsoft.applicationinsights.internal.util.LocalStringsUtils;
27+
2428
import java.io.BufferedWriter;
2529
import java.io.IOException;
2630
import java.io.StringWriter;
2731
import java.io.Writer;
2832
import java.util.*;
2933

30-
import com.google.common.base.Strings;
31-
32-
import com.microsoft.applicationinsights.internal.schemav2.*;
33-
import com.microsoft.applicationinsights.internal.util.LocalStringsUtils;
34-
3534
/**
3635
* This class knows how to transform data that is relevant to {@link Telemetry} instances into JSON.
3736
*/
@@ -273,8 +272,10 @@ private <T> void write(T item) throws IOException {
273272
{
274273
out.write(String.valueOf(item));
275274
} else {
275+
String truncatedName = truncate(String.valueOf(item), 8192);
276+
String sanitizedItem = SanitizationUtils.sanitizeStringForJSON(truncatedName, false);
276277
out.write(JSON_COMMA);
277-
out.write(String.valueOf(item));
278+
out.write(sanitizedItem);
278279
out.write(JSON_COMMA);
279280
}
280281
}
@@ -295,9 +296,11 @@ private <T extends JsonSerializable> String createJsonFor(T value) throws IOExce
295296
}
296297

297298
private void writeName(String name) throws IOException {
299+
String truncatedString = truncate(name, 150);
300+
String sanitizedName = SanitizationUtils.sanitizeStringForJSON(truncatedString, true);
298301
out.write(separator);
299302
out.write(JSON_COMMA);
300-
out.write(name);
303+
out.write(sanitizedName);
301304
out.write(JSON_COMMA);
302305
out.write(JSON_NAME_VALUE_SEPARATOR);
303306
}
@@ -347,4 +350,12 @@ protected void writeEscapedString(String value) throws IOException {
347350
}
348351
}
349352
}
353+
354+
private String truncate(String value, int len) {
355+
if (value.length() > len) {
356+
return value.substring(0, len);
357+
}
358+
return value;
359+
}
360+
350361
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.microsoft.applicationinsights.telemetry;
2+
3+
import java.text.StringCharacterIterator;
4+
5+
/**
6+
* Created by dhdoshi on 09/10/2017
7+
*
8+
* This class provides utility functions to sanitize strings
9+
* for various formats. Currently it supports JSON sanitization
10+
*/
11+
final class SanitizationUtils {
12+
13+
/**
14+
* This method appends escape characters to input String to prevent
15+
* JSON Sanitization failure
16+
* @param text
17+
* @return Sanitized String suitable for JSON
18+
*/
19+
static String sanitizeStringForJSON(String text, boolean isKey) {
20+
21+
final StringBuilder result = new StringBuilder();
22+
StringCharacterIterator iterator = new StringCharacterIterator(text);
23+
24+
// allowing delta for the characters to be appended
25+
int maxAllowedLength = isKey ? 148 : 8190;
26+
for (char curr = iterator.current(); curr != iterator.DONE && result.length() < maxAllowedLength; curr = iterator.next()) {
27+
if( curr == '\"' ){
28+
result.append("\\\"");
29+
}
30+
else if (curr == '\'') {
31+
result.append("\\\'");
32+
}
33+
else if(curr == '\\'){
34+
result.append("\\\\");
35+
}
36+
else if(curr == '/'){
37+
result.append("\\/");
38+
}
39+
else if(curr == '\b'){
40+
result.append("\\b");
41+
}
42+
else if(curr == '\f'){
43+
result.append("\\f");
44+
}
45+
else if(curr == '\n'){
46+
result.append("\\n");
47+
}
48+
else if(curr == '\r'){
49+
result.append("\\r");
50+
}
51+
else if(curr == '\t'){
52+
result.append("\\t");
53+
}
54+
else if (!Character.isISOControl(curr)){
55+
result.append(curr);
56+
}
57+
else {
58+
if (result.length() + 7 < 8192) { // needs 7 more character space to be appended
59+
result.append("\\u");
60+
result.append((String.format( "%04x", Integer.valueOf(curr))));
61+
}
62+
else {
63+
break;
64+
}
65+
}
66+
}
67+
return result.toString();
68+
}
69+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.microsoft.applicationinsights.telemetry;
2+
3+
import com.microsoft.applicationinsights.telemetry.SanitizationUtils;
4+
import org.junit.Assert;
5+
import org.junit.Test;
6+
7+
public class SanitizationUtilsTests {
8+
9+
@Test
10+
public void testSanitizeStringForJSON() {
11+
12+
String result1 = SanitizationUtils.sanitizeStringForJSON("\\'\\f\\b\\f\\n\\r\\t/\\", false);
13+
Assert.assertEquals(result1, "\\\\\\'\\\\f\\\\b\\\\f\\\\n\\\\r\\\\t\\/\\\\");
14+
15+
String resultControlCharVer = SanitizationUtils.sanitizeStringForJSON("\u0000", true);
16+
Assert.assertEquals(resultControlCharVer, "\\u0000");
17+
}
18+
}

0 commit comments

Comments
 (0)