-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move ambiguous object field name detection into DotExpandingXContentParser #82359
Changes from all commits
2d775fd
eb277d3
82ef34c
019f633
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,7 +48,7 @@ public Token nextToken() throws IOException { | |
|
||
private void expandDots() throws IOException { | ||
String field = delegate().currentName(); | ||
String[] subpaths = field.split("\\."); | ||
String[] subpaths = splitAndValidatePath(field); | ||
if (subpaths.length == 0) { | ||
throw new IllegalArgumentException("field name cannot contain only dots: [" + field + "]"); | ||
} | ||
|
@@ -71,6 +71,31 @@ protected XContentParser delegate() { | |
} | ||
} | ||
|
||
private static String[] splitAndValidatePath(String fullFieldPath) { | ||
if (fullFieldPath.isEmpty()) { | ||
throw new IllegalArgumentException("field name cannot be an empty string"); | ||
} | ||
if (fullFieldPath.contains(".") == false) { | ||
return new String[] { fullFieldPath }; | ||
} | ||
String[] parts = fullFieldPath.split("\\."); | ||
if (parts.length == 0) { | ||
throw new IllegalArgumentException("field name cannot contain only dots"); | ||
} | ||
for (String part : parts) { | ||
// check if the field name contains only whitespace | ||
if (part.isEmpty()) { | ||
throw new IllegalArgumentException("object field cannot contain only whitespace: ['" + fullFieldPath + "']"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @romseygeek is the mention of "object" in this error and the next one accurate? Don't we split any path regardless of the token we are reading from the parser? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes I think that's a leftover, and it was probably inaccurate even before this change. It should be 'field name' |
||
} | ||
if (part.isBlank()) { | ||
throw new IllegalArgumentException( | ||
"object field starting or ending with a [.] makes object resolution ambiguous: [" + fullFieldPath + "]" | ||
); | ||
} | ||
} | ||
return parts; | ||
} | ||
|
||
/** | ||
* Wraps an XContentParser such that it re-interprets dots in field names as an object structure | ||
* @param in the parser to wrap | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -461,7 +461,6 @@ private static void innerParseObject(DocumentParserContext context, ObjectMapper | |
while (token != XContentParser.Token.END_OBJECT) { | ||
if (token == XContentParser.Token.FIELD_NAME) { | ||
currentFieldName = context.parser().currentName(); | ||
splitAndValidatePath(currentFieldName); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it ok to omit this call now? What was it doing and where is that method called now? Seems like the new method incorporates some of its logic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The new method is pretty much a straight copy. It's called in the DotExpandingXContentParser, which InternalDocumentParserContext creates to wrap the source document's xcontent parser. The existing call sites were places where we previously split up field names, but that all happens in the expanding parser now so it makes more sense to handle things there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok then I guess I am unclear on why the original method stays around, are there still places where we call it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep it's still called from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, thanks! Can we in the meantime share the code between the two then, or are there subtle differences? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are slightly different because the x-content lib doesn't have access to |
||
} else if (token == XContentParser.Token.START_OBJECT) { | ||
parseObject(context, mapper, currentFieldName); | ||
} else if (token == XContentParser.Token.START_ARRAY) { | ||
|
@@ -649,7 +648,6 @@ private static void parseNonDynamicArray( | |
) throws IOException { | ||
XContentParser parser = context.parser(); | ||
XContentParser.Token token; | ||
splitAndValidatePath(lastFieldName); | ||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { | ||
if (token == XContentParser.Token.START_OBJECT) { | ||
parseObject(context, mapper, lastFieldName); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romseygeek this check is redundant now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, good catch