Skip to content

Commit

Permalink
Use possessive quantifiers in regex for decoding cookies
Browse files Browse the repository at this point in the history
Decoding cookies becomes very complex to handle for the regex engine
when cookie values are very large. This causes `StackOverflowError`s
probable due to the catastrophic backtracking

Use possessive quantifiers to prevent the regex engine from trying
all permutations. This should make the complexity of the regex linear
and not exponential. The performance increase can be significant and
fixes the issue.

Closes #77
  • Loading branch information
testinfected committed Dec 22, 2020
1 parent b6eff3a commit 8513d31
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main/java/com/vtence/molecule/http/CookieDecoder.java
Expand Up @@ -7,7 +7,7 @@

public class CookieDecoder {

private static final Pattern NAME_VALUE_PAIR = Pattern.compile("(?:\\s|[;,])*([^;=]+)(?:=([\"]((?:\\\\\"|[^\"])*)[\"]|[^;,]*))?");
private static final Pattern NAME_VALUE_PAIR = Pattern.compile("(?:\\s|[;,])*+([^;=]++)(?:=([\"]((?:\\\\\"|[^\"])++)[\"]|[^;,]*+))?+");

private static final int NAME = 1;
private static final int VALUE = 2;
Expand Down
7 changes: 7 additions & 0 deletions src/test/java/com/vtence/molecule/http/CookieDecoderTest.java
@@ -1,5 +1,6 @@
package com.vtence.molecule.http;

import org.hamcrest.Matchers;
import org.junit.Test;

import java.util.List;
Expand Down Expand Up @@ -132,6 +133,12 @@ public void decodesCommaSeparatedPairs() {
assertThat("cookie value", launcher.value(), equalTo("Rocket_Launcher_0001"));
}

@Test
public void handlesVeryLongCookieValue() {
Cookie cookie = decodeSingle("$Version=\"1\"; molecule.session=\"rO0ABXNyACNjb20udnRlbmNlLm1vbGVjdWxlLnNlc3Npb24uU2Vzc2lvbvJqkJ0nBioiAgAGWgAHaW52YWxpZEkABm1heEFnZUwACmF0dHJpYnV0ZXN0AA9MamF2YS91dGlsL01hcDtMAAljcmVhdGVkQXR0ABNMamF2YS90aW1lL0luc3RhbnQ7TAACaWR0ABJMamF2YS9sYW5nL1N0cmluZztMAAl1cGRhdGVkQXRxAH4AAnhwAP////9zcgAmamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXBkmd4SnYcpPQMAA0kAC3NlZ21lbnRNYXNrSQAMc2VnbWVudFNoaWZ0WwAIc2VnbWVudHN0ADFbTGphdmEvdXRpbC9jb25jdXJyZW50L0NvbmN1cnJlbnRIYXNoTWFwJFNlZ21lbnQ7eHAAAAAPAAAAHHVyADFbTGphdmEudXRpbC5jb25jdXJyZW50LkNvbmN1cnJlbnRIYXNoTWFwJFNlZ21lbnQ7Unc/QTKbOXQCAAB4cAAAABBzcgAuamF2YS51dGlsLmNvbmN1cnJlbnQuQ29uY3VycmVudEhhc2hNYXAkU2VnbWVudB82TJBYkyk9AgABRgAKbG9hZEZhY3RvcnhyAChqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrZlWoLCzIausCAAFMAARzeW5jdAAvTGphdmEvdXRpbC9jb25jdXJyZW50L2xvY2tzL1JlZW50cmFudExvY2skU3luYzt4cHNyADRqYXZhLnV0aWwuY29uY3VycmVudC5sb2Nrcy5SZWVudHJhbnRMb2NrJE5vbmZhaXJTeW5jZYgy51N7vwsCAAB4cgAtamF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuUmVlbnRyYW50TG9jayRTeW5juB6ilKpEWnwCAAB4cgA1amF2YS51dGlsLmNvbmN1cnJlbnQubG9ja3MuQWJzdHJhY3RRdWV1ZWRTeW5jaHJvbml6ZXJmVahDdT9S4wIAAUkABXN0YXRleHIANmphdmEudXRpbC5jb25jdXJyZW50LmxvY2tzLkFic3RyYWN0T3duYWJsZVN5bmNocm9uaXplcjPfr7mtbW+pAgAAeHAAAAAAP0AAAHNxAH4ACnNxAH4ADgAAAAA/QAAAc3EAfgAKc3EAfgAOAAAAAD9AAABzcQB+AApzcQB+AA4AAAAAP0AAAHNxAH4ACnNxAH4ADgAAAAA/QAAAc3EAfgAKc3EAfgAOAAAAAD9AAABzcQB+AApzcQB+AA4AAAAAP0AAAHNxAH4ACnNxAH4ADgAAAAA/QAAAc3EAfgAKc3EAfgAOAAAAAD9AAABzcQB+AApzcQB+AA4AAAAAP0AAAHNxAH4ACnNxAH4ADgAAAAA/QAAAc3EAfgAKc3EAfgAOAAAAAD9AAABzcQB+AApzcQB+AA4AAAAAP0AAAHNxAH4ACnNxAH4ADgAAAAA/QAAAc3EAfgAKc3EAfgAOAAAAAD9AAABzcQB+AApzcQB+AA4AAAAAP0AAAHQACHVzZXJuYW1ldAAHVmluY2VudHBweHNyAA1qYXZhLnRpbWUuU2VylV2EuhsiSLIMAAB4cHcNAgAAAABf4YaaJOx4CHh0ACRjNGIxMDNlMC0zYzAzLTQxZDYtOWEzNC1lZTczOWE3ODc0YzBxAH4ANA==--r3q1yut2aSCAjMF03DMV2z5A79aeWP744I2pMVoO7qk=\";$Path=\"/\";$Domain=\"0.0.0.0\"");
assertThat(cookie.value(), Matchers.endsWith("MVoO7qk="));
}

private Cookie decodeSingle(String cookieHeader) {
List<Cookie> cookies = decodeAll(cookieHeader);
assertThat("cookies found", cookies, hasSize(1));
Expand Down

0 comments on commit 8513d31

Please sign in to comment.