Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 526599a

Browse files
author
Petr Bouda
committed
JERSEY-2656: Form parameters without equal sign are processed with Null value
Change-Id: I99357c3b03dcc27282901a274a8b3fd8eb6e8eec
1 parent dc607ba commit 526599a

File tree

5 files changed

+298
-8
lines changed

5 files changed

+298
-8
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.jersey.internal.util.collection;
41+
42+
import java.util.List;
43+
44+
import javax.ws.rs.core.MultivaluedHashMap;
45+
import javax.ws.rs.core.MultivaluedMap;
46+
47+
/**
48+
* An implementation of {@link MultivaluedMap} where values can be {@code null}.
49+
*
50+
* @param <K> the type of keys maintained by this map
51+
* @param <V> the type of mapped values which can contain {@code null} values
52+
*
53+
* @author Petr Bouda (petr.bouda at oracle.com)
54+
*/
55+
public class NullableMultivaluedHashMap<K, V> extends MultivaluedHashMap<K, V> {
56+
57+
public NullableMultivaluedHashMap() {
58+
super();
59+
}
60+
61+
public NullableMultivaluedHashMap(int initialCapacity) {
62+
super(initialCapacity);
63+
}
64+
65+
public NullableMultivaluedHashMap(int initialCapacity, float loadFactor) {
66+
super(initialCapacity, loadFactor);
67+
}
68+
69+
public NullableMultivaluedHashMap(MultivaluedMap<? extends K, ? extends V> map) {
70+
super(map);
71+
}
72+
73+
@Override
74+
protected void addFirstNull(final List<V> values) {
75+
values.add(null);
76+
}
77+
78+
@Override
79+
protected void addNull(final List<V> values) {
80+
values.add(null);
81+
}
82+
}

core-common/src/main/java/org/glassfish/jersey/message/internal/FormMultivaluedMapProvider.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2010-2015 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -49,11 +49,12 @@
4949
import javax.ws.rs.Consumes;
5050
import javax.ws.rs.Produces;
5151
import javax.ws.rs.core.MediaType;
52-
import javax.ws.rs.core.MultivaluedHashMap;
5352
import javax.ws.rs.core.MultivaluedMap;
5453

5554
import javax.inject.Singleton;
5655

56+
import org.glassfish.jersey.internal.util.collection.NullableMultivaluedHashMap;
57+
5758
/**
5859
* Provider for marshalling/un-marshalling of {@code application/x-www-form-urlencoded}
5960
* entity type to/from {@link MultivaluedMap multi-valued map} instance.
@@ -88,7 +89,7 @@ public MultivaluedMap<String, String> readFrom(
8889
MediaType mediaType,
8990
MultivaluedMap<String, String> httpHeaders,
9091
InputStream entityStream) throws IOException {
91-
return readFrom(new MultivaluedHashMap<String, String>(), mediaType, true, entityStream);
92+
return readFrom(new NullableMultivaluedHashMap<String, String>(), mediaType, true, entityStream);
9293
}
9394

9495
@Override
@@ -107,4 +108,4 @@ public void writeTo(
107108
OutputStream entityStream) throws IOException {
108109
writeTo(t, mediaType, entityStream);
109110
}
110-
}
111+
}

core-common/src/main/java/org/glassfish/jersey/message/internal/FormProvider.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2010-2012 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2010-2015 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -50,11 +50,12 @@
5050
import javax.ws.rs.Produces;
5151
import javax.ws.rs.core.Form;
5252
import javax.ws.rs.core.MediaType;
53-
import javax.ws.rs.core.MultivaluedHashMap;
5453
import javax.ws.rs.core.MultivaluedMap;
5554

5655
import javax.inject.Singleton;
5756

57+
import org.glassfish.jersey.internal.util.collection.NullableMultivaluedHashMap;
58+
5859
/**
5960
* Provider for marshalling/un-marshalling of {@code application/x-www-form-urlencoded}
6061
* entity type to/from {@link Form JAX-RS Form} instance.
@@ -81,7 +82,7 @@ public Form readFrom(
8182
MultivaluedMap<String, String> httpHeaders,
8283
InputStream entityStream) throws IOException {
8384

84-
return new Form(readFrom(new MultivaluedHashMap<String, String>(), mediaType, decode(annotations), entityStream));
85+
return new Form(readFrom(new NullableMultivaluedHashMap<String, String>(), mediaType, decode(annotations), entityStream));
8586
}
8687

8788

@@ -110,4 +111,4 @@ public void writeTo(
110111
OutputStream entityStream) throws IOException {
111112
writeTo(t.asMap(), mediaType, entityStream);
112113
}
113-
}
114+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.jersey.message.internal;
41+
42+
import java.io.ByteArrayInputStream;
43+
import java.io.IOException;
44+
import java.io.InputStream;
45+
import java.lang.annotation.Annotation;
46+
import java.nio.charset.StandardCharsets;
47+
import java.util.List;
48+
49+
import javax.ws.rs.core.MediaType;
50+
import javax.ws.rs.core.MultivaluedHashMap;
51+
import javax.ws.rs.core.MultivaluedMap;
52+
53+
import org.junit.Test;
54+
55+
import static junit.framework.Assert.assertEquals;
56+
import static junit.framework.Assert.assertNull;
57+
58+
/**
59+
* {@link FormProvider} unit tests
60+
*
61+
* @author Petr Bouda (petr.bouda at oracle.com)
62+
*/
63+
public class FormMultivaluedMapProviderTest {
64+
65+
private static final FormMultivaluedMapProvider PROVIDER = new FormMultivaluedMapProvider();
66+
67+
@Test
68+
public void testReadFormParam() {
69+
MultivaluedMap<String, String> map = readFrom("name&age=26");
70+
assertEquals(2, map.size());
71+
72+
List<String> nameEntry = map.get("name");
73+
assertEquals(1, nameEntry.size());
74+
assertNull(nameEntry.get(0));
75+
76+
List<String> ageEntry = map.get("age");
77+
assertEquals(1, ageEntry.size());
78+
assertEquals("26", ageEntry.get(0));
79+
}
80+
81+
@Test
82+
public void testReadMultipleSameFormParam() {
83+
MultivaluedMap<String, String> map = readFrom("name&name=George");
84+
assertEquals(1, map.size());
85+
86+
List<String> nameEntry = map.get("name");
87+
assertEquals(2, nameEntry.size());
88+
assertNull(nameEntry.get(0));
89+
assertEquals("George", nameEntry.get(1));
90+
}
91+
92+
@SuppressWarnings("unchecked")
93+
private static MultivaluedMap<String, String> readFrom(String body) {
94+
try {
95+
InputStream stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
96+
Class<MultivaluedMap<String, String>> clazz =
97+
(Class<MultivaluedMap<String, String>>) (Class<?>) MultivaluedHashMap.class;
98+
return PROVIDER.readFrom(clazz, clazz, new Annotation[] {}, MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, stream);
99+
} catch (IOException e) {
100+
throw new RuntimeException("Unexpected exception", e);
101+
}
102+
}
103+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.jersey.message.internal;
41+
42+
import java.io.ByteArrayInputStream;
43+
import java.io.IOException;
44+
import java.io.InputStream;
45+
import java.lang.annotation.Annotation;
46+
import java.nio.charset.StandardCharsets;
47+
import java.util.List;
48+
49+
import javax.ws.rs.core.Form;
50+
import javax.ws.rs.core.MediaType;
51+
import javax.ws.rs.core.MultivaluedMap;
52+
53+
import org.junit.Test;
54+
55+
import static junit.framework.Assert.assertEquals;
56+
import static junit.framework.Assert.assertNull;
57+
58+
/**
59+
* {@link FormProvider} unit tests
60+
*
61+
* @author Petr Bouda (petr.bouda at oracle.com)
62+
*/
63+
public class FormProviderTest {
64+
65+
private static final FormProvider PROVIDER = new FormProvider();
66+
67+
@Test
68+
public void testReadFormParam() {
69+
Form form = readFrom("name&age=26");
70+
MultivaluedMap<String, String> map = form.asMap();
71+
assertEquals(2, map.size());
72+
73+
List<String> nameEntry = map.get("name");
74+
assertEquals(1, nameEntry.size());
75+
assertNull(nameEntry.get(0));
76+
77+
List<String> ageEntry = map.get("age");
78+
assertEquals(1, ageEntry.size());
79+
assertEquals("26", ageEntry.get(0));
80+
}
81+
82+
@Test
83+
public void testReadMultipleSameFormParam() {
84+
Form form = readFrom("name&name=George");
85+
MultivaluedMap<String, String> map = form.asMap();
86+
assertEquals(1, map.size());
87+
88+
List<String> nameEntry = map.get("name");
89+
assertEquals(2, nameEntry.size());
90+
assertNull(nameEntry.get(0));
91+
assertEquals("George", nameEntry.get(1));
92+
}
93+
94+
private static Form readFrom(String body) {
95+
try {
96+
InputStream stream = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
97+
return PROVIDER.readFrom(Form.class, Form.class, new Annotation[] {},
98+
MediaType.APPLICATION_FORM_URLENCODED_TYPE, null, stream);
99+
} catch (IOException e) {
100+
throw new RuntimeException("Unexpected exception", e);
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)