dzieciou/curl-logger

Failing to escape characters with code higher than 255

schrepfler opened this issue ยท 3 comments

I've picked up this exception on my tests, probably related with payload size.

2020-08-21 10:48:45,033 WARN  [curl] (main) Failed to generate CURL command for HTTP request: java.lang.StringIndexOutOfBoundsException: String index out of range: 4
	at java.lang.String.substring(String.java:1963)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.escapeAsHex(CurlCommand.java:304)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.escape(CurlCommand.java:285)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.lambda$escapeStringPosix$0(CurlCommand.java:255)
	at java.util.stream.IntPipeline$4$1.accept(IntPipeline.java:250)
	at java.lang.CharSequence$1CharIterator.forEachRemaining(CharSequence.java:149)
	at java.util.Spliterators$IntIteratorSpliterator.forEachRemaining(Spliterators.java:1908)
	at java.util.Spliterator$OfInt.forEachRemaining(Spliterator.java:693)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.escapeStringPosix(CurlCommand.java:256)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.escapeString(CurlCommand.java:357)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.lambda$serialize$5(CurlCommand.java:327)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at com.github.dzieciou.testing.curl.CurlCommand$Serializer.serialize(CurlCommand.java:327)
	at com.github.dzieciou.testing.curl.CurlCommand.asString(CurlCommand.java:121)
	at com.github.dzieciou.testing.curl.Http2Curl.generateCurl(Http2Curl.java:161)
	at com.github.dzieciou.testing.curl.CurlLoggingInterceptor.process(CurlLoggingInterceptor.java:38)
	at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:133)
	at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:167)
	at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
	at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:835)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.apache.http.client.HttpClient$execute$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at org.apache.http.client.HttpClient$execute$0.call(Unknown Source)
	at io.restassured.internal.RequestSpecificationImpl$RestAssuredHttpBuilder.doRequest(RequestSpecificationImpl.groovy:2055)
	at io.restassured.internal.http.HTTPBuilder.doRequest(HTTPBuilder.java:495)
	at io.restassured.internal.http.HTTPBuilder.request(HTTPBuilder.java:452)
	at io.restassured.internal.http.HTTPBuilder$request$2.call(Unknown Source)
	at io.restassured.internal.RequestSpecificationImpl.sendHttpRequest(RequestSpecificationImpl.groovy:1451)
	at sun.reflect.GeneratedMethodAccessor245.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1262)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1029)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:816)
	at groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:45)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:55)
	at io.restassured.internal.RequestSpecificationImpl.sendRequest(RequestSpecificationImpl.groovy:1200)
	at sun.reflect.GeneratedMethodAccessor198.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1262)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1029)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:816)
	at groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:45)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:166)
	at io.restassured.internal.filter.SendRequestFilter.filter(SendRequestFilter.groovy:30)
	at io.restassured.filter.Filter$filter$0.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at io.restassured.filter.Filter$filter.call(Unknown Source)
	at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72)
	at io.restassured.filter.time.TimingFilter.filter(TimingFilter.java:56)
	at io.restassured.filter.Filter$filter.call(Unknown Source)
	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
	at io.restassured.filter.Filter$filter$0.call(Unknown Source)
	at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72)
	at io.restassured.filter.FilterContext$next.call(Unknown Source)
	at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1655)
	at sun.reflect.GeneratedMethodAccessor192.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1262)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1029)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:816)
	at groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:45)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:55)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203)
	at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1661)
	at sun.reflect.GeneratedMethodAccessor191.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1262)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1029)
	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:816)
	at groovy.lang.GroovyObject.invokeMethod(GroovyObject.java:39)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:45)
	at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:55)
	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:203)

Thanks for reporting it. The bug you found is valid. Escaping was not properly handling characters with more than 8bits (of code > 255).

Your solution in pull request #48 goes in the right direction, but it lacks \x or \u prefix.

I have provided pull request #52 to fix that.

@schrepfler, are you able to verify the fix before merging this pull request?

Awesome work @dzieciou, I'm not working actively anymore on the bit of code that was having the issue but I'll see what I can do. If I don't manage to validate it by Monday means I got distracted with other work, but looks good! ๐Ÿ‘๐Ÿ‘๐Ÿ‘

So, I've tried it but can't validate because it's not logging anything for me, however I don't think this is issue with curl-logger as much as the fact I'm using Quarkus... maybe.