From 51d6d102bba461120e706f5c799a0ab9e438f3b1 Mon Sep 17 00:00:00 2001 From: naomichi-y Date: Wed, 8 May 2024 19:15:04 +0900 Subject: [PATCH] Fix parseToken array popping Signed-off-by: naomichi-y --- .../xcontent/JsonToStringXContentParser.java | 29 +++++++++++-------- .../JsonToStringXContentParserTests.java | 21 ++++++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/server/src/main/java/org/opensearch/common/xcontent/JsonToStringXContentParser.java b/server/src/main/java/org/opensearch/common/xcontent/JsonToStringXContentParser.java index 9b2bd06a88e2e..1869c809400ce 100644 --- a/server/src/main/java/org/opensearch/common/xcontent/JsonToStringXContentParser.java +++ b/server/src/main/java/org/opensearch/common/xcontent/JsonToStringXContentParser.java @@ -65,7 +65,7 @@ public JsonToStringXContentParser( public XContentParser parseObject() throws IOException { builder.startObject(); StringBuilder path = new StringBuilder(fieldTypeName); - parseToken(path, null); + parseToken(path, null, true); builder.field(this.fieldTypeName, keyList); builder.field(this.fieldTypeName + VALUE_SUFFIX, valueList); builder.field(this.fieldTypeName + VALUE_AND_PATH_SUFFIX, valueAndPathList); @@ -74,8 +74,7 @@ public XContentParser parseObject() throws IOException { return JsonXContent.jsonXContent.createParser(this.xContentRegistry, this.deprecationHandler, String.valueOf(jString)); } - private void parseToken(StringBuilder path, String currentFieldName) throws IOException { - + private void parseToken(StringBuilder path, String currentFieldName, boolean popName) throws IOException { while (this.parser.nextToken() != Token.END_OBJECT) { if (this.parser.currentName() != null) { currentFieldName = this.parser.currentName(); @@ -100,15 +99,18 @@ private void parseToken(StringBuilder path, String currentFieldName) throws IOEx this.keyList.add(fieldNameSuffix); } } else if (this.parser.currentToken() == Token.START_ARRAY) { - parseToken(path, currentFieldName); + parseToken(path, currentFieldName, false); break; } else if (this.parser.currentToken() == Token.END_ARRAY) { // skip } else if (this.parser.currentToken() == Token.START_OBJECT) { - parseToken(path, currentFieldName); - int dotIndex = path.lastIndexOf(DOT_SYMBOL); - if (dotIndex != -1) { - path.setLength(path.length() - currentFieldName.length() - 1); + parseToken(path, currentFieldName, true); + + if (popName) { + int dotIndex = path.lastIndexOf(DOT_SYMBOL); + if (dotIndex != -1) { + path.setLength(path.length() - currentFieldName.length() - 1); + } } } else { if (!path.toString().contains(currentFieldName)) { @@ -117,12 +119,15 @@ private void parseToken(StringBuilder path, String currentFieldName) throws IOEx parseValue(parsedFields); this.valueList.add(parsedFields.toString()); this.valueAndPathList.add(path + EQUAL_SYMBOL + parsedFields); - int dotIndex = path.lastIndexOf(DOT_SYMBOL); - if (dotIndex != -1) { - path.setLength(path.length() - currentFieldName.length() - 1); + + if (popName) { + int dotIndex = path.lastIndexOf(DOT_SYMBOL); + + if (dotIndex != -1) { + path.setLength(path.length() - currentFieldName.length() - 1); + } } } - } } diff --git a/server/src/test/java/org/opensearch/common/xcontent/JsonToStringXContentParserTests.java b/server/src/test/java/org/opensearch/common/xcontent/JsonToStringXContentParserTests.java index 0feb7bcd1ceec..479c62be0abbd 100644 --- a/server/src/test/java/org/opensearch/common/xcontent/JsonToStringXContentParserTests.java +++ b/server/src/test/java/org/opensearch/common/xcontent/JsonToStringXContentParserTests.java @@ -110,4 +110,25 @@ public void testNestChildObjectWithDotsAndFieldWithDots() throws IOException { ); } + public void testArrayOfObjects() throws IOException { + String jsonExample ="{" + + "\"field\": {" + + " \"detail\": {" + + " \"foooooooooooo\": [" + + " {\"name\":\"baz\"}," + + " {\"name\":\"baz\"}" + + " ]" + + " }" + + "}}"; + + assertEquals("{" + + "\"flat\":[\"field\",\"detail\",\"foooooooooooo\",\"name\",\"name\"]," + + "\"flat._value\":[\"baz\",\"baz\"]," + + "\"flat._valueAndPath\":[" + + "\"flat.field.detail.foooooooooooo.name=baz\"," + + "\"flat.field.detail.foooooooooooo.name=baz\"" + + "]}", + flattenJsonString("flat", jsonExample) + ); + } }