Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

Fix #14: Decoding fails when two encoded characters appear one after another #21

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ jdk:
- openjdk12
- openjdk13
- openjdk14

29 changes: 25 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/js-cookie/java-cookie.git"
},
"devDependencies": {
"bower": "1.8.8"
"bower": "1.8.12"
},
"scripts": {
"test": "cd bower_components/js-cookie && ../../node/node \"../../node/node_modules/npm/bin/npm-cli.js\" install"
Expand Down
17 changes: 8 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<selenium.version>2.45.0</selenium.version>
<selenium.version>3.141.59</selenium.version>
<wildfly.version>20.0.1.Final</wildfly.version>
<project.scm.id>java-cookie-scm</project.scm.id>
<java.version>1.8</java.version>
Expand Down Expand Up @@ -86,17 +86,17 @@
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
<version>2.10.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -150,13 +150,13 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
<version>4.5.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.12</version>
<version>4.5.13</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down Expand Up @@ -208,16 +208,15 @@
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.10.0</version>
<version>1.11.2</version>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
<configuration>
<nodeVersion>v12.18.2</nodeVersion>
<!--<npmVersion>6.8.0</npmVersion>-->
<nodeVersion>v15.6.0</nodeVersion>
</configuration>
</execution>
<execution>
Expand Down
67 changes: 26 additions & 41 deletions src/main/java/com/github/jscookie/javacookie/Cookies.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package com.github.jscookie.javacookie;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public final class Cookies implements CookiesDefinition {
private static String UTF_8 = "UTF-8";
Expand Down Expand Up @@ -307,42 +305,30 @@ private String encode( String decoded, Set<Integer> exceptions ) {
String character = new String( Character.toChars( codePoint ) );
CharArrayWriter hexSequence = new CharArrayWriter();
byte[] bytes = character.getBytes( UTF_8 );
for ( int bytesIndex = 0; bytesIndex < bytes.length; bytesIndex++ ) {
char left = Character.forDigit( bytes[ bytesIndex ] >> 4 & 0xF, 16 );
char right = Character.forDigit( bytes[ bytesIndex ] & 0xF, 16 );
for (byte aByte : bytes) {
char left = Character.forDigit(aByte >> 4 & 0xF, 16);
char right = Character.forDigit(aByte & 0xF, 16);
hexSequence
.append( '%' )
.append( left )
.append( right );
.append('%')
.append(left)
.append(right);
}
String target = character.toString();
String sequence = hexSequence.toString().toUpperCase();
encoded = encoded.replace( target, sequence );
encoded = encoded.replace(character, sequence );
} catch ( UnsupportedEncodingException e ) {
e.printStackTrace();
}
}
return encoded;
}

private String decode( String encoded ) {
private String decode(String encoded) {
// Use URLDecoder to fix https://github.com/js-cookie/java-cookie/issues/14
String decoded = encoded;
Pattern pattern = Pattern.compile( "(%[0-9A-Z]{2})+" );
Matcher matcher = pattern.matcher( encoded );
while ( matcher.find() ) {
String encodedChar = matcher.group();
String[] encodedBytes = encodedChar.split( "%" );
byte[] bytes = new byte[ encodedBytes.length - 1 ];
for ( int i = 1; i < encodedBytes.length; i++ ) {
String encodedByte = encodedBytes[ i ];
bytes[ i - 1 ] = ( byte )Integer.parseInt( encodedByte, 16 );
}
try {
String decodedChar = new String( bytes, UTF_8 );
decoded = decoded.replace( encodedChar, decodedChar );
} catch ( UnsupportedEncodingException e ) {
try {
decoded = URLDecoder.decode(encoded, UTF_8);
} catch ( UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return decoded;
}
Expand Down Expand Up @@ -403,14 +389,13 @@ private String decodeValue( String encodedValue, String decodedName ) {
private Map<String, String> getCookies( String cookieHeader ) {
Map<String, String> result = new HashMap<String, String>();
String[] cookies = cookieHeader.split( "; " );
for ( int i = 0; i < cookies.length; i++ ) {
String cookie = cookies[ i ];
String encodedName = cookie.split( "=" )[ 0 ];
String decodedName = decode( encodedName );

String encodedValue = cookie.substring( cookie.indexOf( '=' ) + 1, cookie.length() );
String decodedValue = decodeValue( encodedValue, decodedName );
result.put( decodedName, decodedValue );
for (String cookie : cookies) {
String encodedName = cookie.split("=")[0];
String decodedName = decode(encodedName);

String encodedValue = cookie.substring(cookie.indexOf('=') + 1);
String decodedValue = decodeValue(encodedValue, decodedName);
result.put(decodedName, decodedValue);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ public static Archive<?> createDeployment() {
"web.xml"
);

System.out.println( " ----- LOGGING THE FILES ADDED TO JBOSS" );
System.out.println( war.toString( true ) );
System.out.println( " ----- END OF LOGGING THE FILES ADDED TO JBOSS" );
if(debug.is(true)) {
System.out.println(" ----- LOGGING THE FILES ADDED TO JBOSS");
System.out.println(war.toString(true));
System.out.println(" ----- END OF LOGGING THE FILES ADDED TO JBOSS");
}

return war;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,27 @@ public void character_not_allowed_in_name_and_value() {
Assert.assertEquals( expected, actual );
}

@Test
public void character_with_2_bytes() {
Mockito.when( request.getHeader( "cookie" ) ).thenReturn( "c=%C3%A3" );
String actual = cookies.get( "c" );
String expected = "ã";
Assert.assertEquals( expected, actual );
}
Comment on lines +30 to +36
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case is failing.., (its also failing in Travis CI builds - https://travis-ci.org/github/js-cookie/java-cookie/builds/764105675)
java-cookie pr reivew faing junit

@tholu check this failing test case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JevinMenezes Yes, I explicitly added the test case here: 88b8327

Thanks for the reminder! Did not have time yet to fix the issue, will try to get this done over the weekend.


@Test
public void character_with_3_bytes() {
Mockito.when( request.getHeader( "cookie" ) ).thenReturn( "c=%E4%BA%AC" );
String actual = cookies.get( "c" );
String expected = "京";
Assert.assertEquals( expected, actual );
}

@Test
public void two_encoded_characters() {
Mockito.when(request.getHeader("cookie")).thenReturn("c=New%20York%2C%20NY");
String actual = cookies.get("c");
String expected = "New York, NY";
Assert.assertEquals(expected, actual);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ public void characters_allowed_in_name_and_value() {
);
}

@Test
public void character_with_2_bytes_in_value() {
cookies.set( "c", "ã" );
Mockito.verify( response ).addHeader( "Set-Cookie", "c=%C3%A3; Path=/" );
}

@Test
public void character_with_3_bytes_in_value() {
cookies.set( "c", "京" );
Expand Down