Skip to content
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

StackOverflow for JsonBodyFilter #689

Closed
Sam-Kruglov opened this issue Jan 15, 2020 · 20 comments
Closed

StackOverflow for JsonBodyFilter #689

Sam-Kruglov opened this issue Jan 15, 2020 · 20 comments

Comments

@Sam-Kruglov
Copy link

Sam-Kruglov commented Jan 15, 2020

Using a debugger, I built a function that will reproduce it (this is inside com.monese.card.service.config.logbook.JsonBodyFilters#replace inside delegate lambda):
Screenshot 2020-01-15 at 20 04 55

public static void main(String[] args) {
    //com.monese.card.service.config.logbook.JsonBodyFilters#replace
    String STRING = "(?:\"(?:[^\"\\\\]|\\\\.)*\")";
    String value = STRING;
    final Pattern pattern = compile("(?<key>\"(?<property>.*?)\"\\s*:\\s*)(" + value + "|null)");
    String body = "{\"variables\":{},\"query\":\"\\n    query IntrospectionQuery {\\n      __schema {\\n        queryType { name }\\n        mutationType { name }\\n        subscriptionType { name }\\n        types {\\n          ...FullType\\n        }\\n        directives {\\n          name\\n          description\\n          locations\\n          args {\\n            ...InputValue\\n          }\\n        }\\n      }\\n    }\\n\\n    fragment FullType on __Type {\\n      kind\\n      name\\n      description\\n      fields(includeDeprecated: true) {\\n        name\\n        description\\n        args {\\n          ...InputValue\\n        }\\n        type {\\n          ...TypeRef\\n        }\\n        isDeprecated\\n        deprecationReason\\n      }\\n      inputFields {\\n        ...InputValue\\n      }\\n      interfaces {\\n        ...TypeRef\\n      }\\n      enumValues(includeDeprecated: true) {\\n        name\\n        description\\n        isDeprecated\\n        deprecationReason\\n      }\\n      possibleTypes {\\n        ...TypeRef\\n      }\\n    }\\n\\n    fragment InputValue on __InputValue {\\n      name\\n      description\\n      type { ...TypeRef }\\n      defaultValue\\n    }\\n\\n    fragment TypeRef on __Type {\\n      kind\\n      name\\n      ofType {\\n        kind\\n        name\\n        ofType {\\n          kind\\n          name\\n          ofType {\\n            kind\\n            name\\n            ofType {\\n              kind\\n              name\\n              ofType {\\n                kind\\n                name\\n                ofType {\\n                  kind\\n                  name\\n                  ofType {\\n                    kind\\n                    name\\n                  }\\n                }\\n              }\\n            }\\n          }\\n        }\\n      }\\n    }\\n  \"}";
    pattern.matcher(body).find();
}
@PascalSchumacher
Copy link
Contributor

This is proably the same proablem as the one reported in #686

@Sam-Kruglov
Copy link
Author

I think it failed on rc6 as well tho

@whiskeysierra
Copy link
Collaborator

@PascalSchumacher It's related, yes. But the issue with long was fixed (my test uses a property with 10,000 characters or something like that. I believe the issue now is that there are many " in there which require backtracking.

@whiskeysierra
Copy link
Collaborator

@Sam-Kruglov Thanks for the issue and the test/input! 🎉

@whiskeysierra
Copy link
Collaborator

@Sam-Kruglov Can you share your configuration, i.e. set of property names and replacement? My local test with that input works. Which version are you running?

@Sam-Kruglov
Copy link
Author

Sam-Kruglov commented Jan 16, 2020

It's rc8. What exactly do you need apart what's on the screenshot?

@whiskeysierra
Copy link
Collaborator

The predicate or set of property names. Can you try to write a test that reproduces this locally? Seems to work for me... 🤔

@Sam-Kruglov
Copy link
Author

So the main function doesn't throw an error for you when you run it? For me it fails

@PascalSchumacher
Copy link
Contributor

PascalSchumacher commented Jan 16, 2020

@PascalSchumacher It's related, yes. But the issue with long was fixed (my test uses a property with 10,000 characters or something like that. I believe the issue now is that there are many " in there which require backtracking.

I think you are mixing up #681 and #686. #681 was for long property values. Thanks again for fixing this in RC.8. I successfully tested values to up to 300.000 chars (didn't bother testing even longer values) using RC.8.

#686 is for long property values containg (a lot of) escaped double qoutes. The unit test in the issue will allow you to reproduce the problem.

@whiskeysierra
Copy link
Collaborator

Good point. Seems I was overwhelmed with StackOverflowErrors recently...

@whiskeysierra whiskeysierra added this to the 2.1.0 milestone Jan 23, 2020
@whiskeysierra
Copy link
Collaborator

This is proably the same proablem as the one reported in #686

The sample input has no double quotes. So I'm kind of lost why this one fails, especially since I can't reproduce it.

@whiskeysierra
Copy link
Collaborator

@Sam-Kruglov I added your test input as an additional test case in #712 (aiming to fix #686). It already passed with on my machine before the changes though. Maybe you could verify if that branch builds locally for you. I'm out of ideas how to reproduce that, to be honest.

@Sam-Kruglov
Copy link
Author

I'm using jdk11, are you? I will try tomorrow

@whiskeysierra
Copy link
Collaborator

Usually not, but I just tried and current master works as well with 11.

@whiskeysierra
Copy link
Collaborator

@Sam-Kruglov Did you have a chance to try?

@Sam-Kruglov
Copy link
Author

I tried using open jdk 11.0.1 and 11.0.3 that I have installed. I launched it from intellij and got the stack overflow. Not sure how it works for you...

@Sam-Kruglov
Copy link
Author

oracle jdk 1.8.0_192 on a clean project with no dependencies - same stack overflow. Try copy-pasting the main method from my first message

@whiskeysierra
Copy link
Collaborator

whiskeysierra commented Feb 15, 2020 via email

@whiskeysierra
Copy link
Collaborator

So I took another look and your code sample inlined patterns that are no longer in use.

There is a test case in the master that covers your sample input and it passes ✔️

@Test
void supportsVeryLargeEmbeddedJsonValues() throws IOException {
final byte[] bytes = Files.readAllBytes(Paths.get("src/test/resources/huge-json-value.json"));
final String original = new String(bytes, UTF_8);
final BodyFilter unit = replaceJsonStringProperty(singleton("variables"), "XXX");
final String actual = unit.filter(contentType, original);
assertThat(actual, is(original));
}

{
"variables": {},
"query": "\n query IntrospectionQuery {\n __schema {\n queryType { name }\n mutationType { name }\n subscriptionType { name }\n types {\n ...FullType\n }\n directives {\n name\n description\n locations\n args {\n ...InputValue\n }\n }\n }\n }\n\n fragment FullType on __Type {\n kind\n name\n description\n fields(includeDeprecated: true) {\n name\n description\n args {\n ...InputValue\n }\n type {\n ...TypeRef\n }\n isDeprecated\n deprecationReason\n }\n inputFields {\n ...InputValue\n }\n interfaces {\n ...TypeRef\n }\n enumValues(includeDeprecated: true) {\n name\n description\n isDeprecated\n deprecationReason\n }\n possibleTypes {\n ...TypeRef\n }\n }\n\n fragment InputValue on __InputValue {\n name\n description\n type { ...TypeRef }\n defaultValue\n }\n\n fragment TypeRef on __Type {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n ofType {\n kind\n name\n }\n }\n }\n }\n }\n }\n }\n }\n "
}

@Sam-Kruglov
Copy link
Author

Thanks for taking a deep look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants