Skip to content

Commit

Permalink
Implement radix-trie
Browse files Browse the repository at this point in the history
  • Loading branch information
gavlyukovskiy committed Sep 19, 2024
1 parent 2458b81 commit 0702a2d
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 179 deletions.
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,17 @@ tasks {
"RedundantOverride",
"RedundantThrows",
"RemoveUnusedImports",
"DefaultCharset",
"UnnecessarilyFullyQualified",
"UnnecessarilyUsedValue",
"UnnecessaryBoxedAssignment",
"UnnecessaryBoxedVariable",
"UnnecessaryFinal",
"UnusedException",
"UnusedLabel",
"UnusedMethod",
"UnusedNestedClass",
"UnusedVariable",
"WildcardImport",
)
disable(
Expand Down Expand Up @@ -208,4 +213,4 @@ tasks {
withType<SonarTask> {
dependsOn(jacocoTestReport)
}
}
}
436 changes: 270 additions & 166 deletions src/main/java/dev/blaauwendraad/masker/json/KeyMatcher.java

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/main/java/dev/blaauwendraad/masker/json/MaskingState.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ final class MaskingState implements ValueMaskerContext {
* Current JSONPath is represented by a stack of segment references.
* A stack is implemented with an array of the trie nodes that reference the end of the segment
*/
private KeyMatcher.@Nullable TrieNode @Nullable [] currentJsonPath = null;
private KeyMatcher.@Nullable StatefulRadixTrieNode @Nullable [] currentJsonPath = null;
private int currentJsonPathHeadIndex = -1;
private int currentValueStartIndex = -1;

public MaskingState(byte[] message, boolean trackJsonPath) {
this.message = message;
if (trackJsonPath) {
currentJsonPath = new KeyMatcher.TrieNode[INITIAL_JSONPATH_STACK_CAPACITY];
currentJsonPath = new KeyMatcher.StatefulRadixTrieNode[INITIAL_JSONPATH_STACK_CAPACITY];
}
}

Expand Down Expand Up @@ -150,7 +150,7 @@ boolean jsonPathEnabled() {
*
* @param trieNode a node in the trie where the new segment ends.
*/
void expandCurrentJsonPath(KeyMatcher.@Nullable TrieNode trieNode) {
void expandCurrentJsonPath(KeyMatcher.@Nullable StatefulRadixTrieNode trieNode) {
if (currentJsonPath != null) {
currentJsonPath[++currentJsonPathHeadIndex] = trieNode;
if (currentJsonPathHeadIndex == currentJsonPath.length - 1) {
Expand All @@ -172,7 +172,7 @@ void backtrackCurrentJsonPath() {
/**
* Returns the TrieNode that references the end of the latest segment in the current jsonpath
*/
public KeyMatcher.@Nullable TrieNode getCurrentJsonPathNode() {
public KeyMatcher.@Nullable StatefulRadixTrieNode getCurrentJsonPathNode() {
if (currentJsonPath != null && currentJsonPathHeadIndex != -1) {
return currentJsonPath[currentJsonPathHeadIndex];
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public static List<JsonMaskerTestInstance> getJsonMaskerTestInstancesFromFile(St
applyConfig(jsonMaskingConfig, builder);
}
JsonMaskingConfig maskingConfig = builder.build();
var input = jsonNode.get("input").toString();
var expectedOutput = jsonNode.get("expectedOutput").toString();
var input = jsonNode.get("input").toPrettyString();
var expectedOutput = jsonNode.get("expectedOutput").toPrettyString();
testInstances.add(new JsonMaskerTestInstance(input, expectedOutput, new KeyContainsMasker(maskingConfig)));
}
return testInstances;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ void shouldMatchJsonPaths() {
""";
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);

KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode();
var node = keyMatcher.getJsonPathRootNode();
node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1);
node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'b'), 1);
assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, 0, node)).isNotNull();
Expand Down Expand Up @@ -150,7 +150,7 @@ void shouldMatchJsonPathArrays() {
""";
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);

KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode();
var node = keyMatcher.getJsonPathRootNode();
node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'a'), 1);
node = keyMatcher.traverseJsonPathSegment(bytes, node, -1, -1);
node = keyMatcher.traverseJsonPathSegment(bytes, node, indexOf(bytes, 'b'), 1);
Expand Down Expand Up @@ -184,7 +184,7 @@ void shouldNotMatchJsonPathPrefix() {
""";
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);

KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode();
var node = keyMatcher.getJsonPathRootNode();
node = keyMatcher.traverseJsonPathSegment(bytes, node, 2, 4);
assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNull();

Expand All @@ -206,7 +206,7 @@ void shouldReturnMaskingConfigForJsonPathInAllowMode() {
""";
byte[] bytes = json.getBytes(StandardCharsets.UTF_8);

KeyMatcher.TrieNode node = keyMatcher.getJsonPathRootNode();
var node = keyMatcher.getJsonPathRootNode();
node = keyMatcher.traverseJsonPathSegment(bytes, node, 2, 7);
assertThat(keyMatcher.getMaskConfigIfMatched(bytes, 0, -1, node)).isNull();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void shouldReturnStringRepresentationForDebugging() {
void jsonPathExceedsCapacity() {
MaskingState maskingState = new MaskingState("[]".getBytes(StandardCharsets.UTF_8), true);
for (int i = 0; i < 101; i++) {
maskingState.expandCurrentJsonPath(KeyMatcher.transform(new KeyMatcher.PreInitTrieNode()));
maskingState.expandCurrentJsonPath(new KeyMatcher.StatefulRadixTrieNode(KeyMatcher.compress(new KeyMatcher.PreInitTrieNode())));
}
Assertions.assertThat(maskingState.getCurrentJsonPathNode()).isNotNull();
}
Expand Down Expand Up @@ -90,4 +90,4 @@ void shouldUseCorrectOffsetWhenThrowingValueMaskerError() {
.isInstanceOf(InvalidJsonException.class)
.hasMessage("Didn't like the value at index 3 at index 19");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,27 @@ private static Stream<JsonMaskerTestInstance> unicodeCharacters() {
}
""",
JsonMasker.getMasker(Set.of("maskMe", "̀", "�", "€", "†", "䀀", "𐍈", "💩"))
),
new JsonMaskerTestInstance("""
{
"¼a": "secret",
"½a": "not secret",
"encoded": {
"\\u00BCa": "***",
"\\u00BDa": "not secret"
}
}
""", """
{
"¼a": "***",
"½a": "not secret",
"encoded": {
"\\u00BCa": "***",
"\\u00BDa": "not secret"
}
}
""",
JsonMasker.getMasker(Set.of("¼a"))
)
);
}
Expand Down

0 comments on commit 0702a2d

Please sign in to comment.