001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.fileupload2.core;
018
019import static org.junit.jupiter.api.Assertions.assertEquals;
020import static org.junit.jupiter.api.Assertions.assertNull;
021
022import java.nio.charset.StandardCharsets;
023
024import org.junit.jupiter.api.Test;
025
026/**
027 * Unit tests for {@link ParameterParser}.
028 */
029public class ParameterParserTest {
030
031    @Test
032    public void testContentTypeParsing() {
033        final var s = "text/plain; Charset=UTF-8";
034        final var parser = new ParameterParser();
035        parser.setLowerCaseNames(true);
036        final var params = parser.parse(s, ';');
037        assertEquals(StandardCharsets.UTF_8.name(), params.get("charset"));
038    }
039
040    // See: https://issues.apache.org/jira/browse/FILEUPLOAD-139
041    @Test
042    public void testFileUpload139() {
043        final var parser = new ParameterParser();
044        var s = "Content-type: multipart/form-data , boundary=AaB03x";
045        var params = parser.parse(s, new char[] { ',', ';' });
046        assertEquals("AaB03x", params.get("boundary"));
047
048        s = "Content-type: multipart/form-data, boundary=AaB03x";
049        params = parser.parse(s, new char[] { ';', ',' });
050        assertEquals("AaB03x", params.get("boundary"));
051
052        s = "Content-type: multipart/mixed, boundary=BbC04y";
053        params = parser.parse(s, new char[] { ',', ';' });
054        assertEquals("BbC04y", params.get("boundary"));
055    }
056
057    /**
058     * Test for <a href="https://issues.apache.org/jira/browse/FILEUPLOAD-199">FILEUPLOAD-199</a>
059     */
060    @Test
061    public void testFileUpload199() {
062        final var parser = new ParameterParser();
063        final var s = "Content-Disposition: form-data; name=\"file\"; filename=\"=?ISO-8859-"
064                + "1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?= =?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=\"\r\n";
065        final var params = parser.parse(s, new char[] { ',', ';' });
066        assertEquals("If you can read this you understand the example.", params.get("filename"));
067    }
068
069    /**
070     * Test for <a href="https://issues.apache.org/jira/browse/FILEUPLOAD-274">FILEUPLOAD-274</a>
071     */
072    @Test
073    public void testFileUpload274() {
074        final var parser = new ParameterParser();
075
076        // Should parse a UTF-8 charset
077        var s = "Content-Disposition: form-data; " + "name=\"file\"; filename*=UTF-8''%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF\r\n";
078        var params = parser.parse(s, new char[] { ',', ';' });
079        assertEquals("\u3053\u3093\u306B\u3061\u306F", params.get("filename")); // filename = "こんにちは" in japanese
080
081        // Should parse ISO-8859-1 charset
082        s = "Content-Disposition: form-data; name=\"file\"; filename*=UTF-8''%70%C3%A2%74%C3%A9\r\n";
083        params = parser.parse(s, new char[] { ',', ';' });
084        assertEquals("\u0070\u00e2\u0074\u00e9", params.get("filename")); // filename = "pâté" in french
085
086        // Should not decode if '*' is not at the end of param-name
087        s = "Content-Disposition: form-data; name=\"file\"; file*name=UTF-8''%61%62%63\r\n";
088        params = parser.parse(s, new char[] { ',', ';' });
089        assertEquals("UTF-8''%61%62%63", params.get("file*name"));
090
091        // Should not decode if param-value does not follow <charset>'<lang>'<encoded>
092        s = "Content-Disposition: form-data; name=\"file\"; filename*=a'bc\r\n";
093        params = parser.parse(s, new char[] { ',', ';' });
094        assertEquals("a'bc", params.get("filename"));
095
096        // Should not decode if param-name doesn't have '*' at end
097        s = "Content-Disposition: form-data; name=\"file\"; filename=a'b'c\r\n";
098        params = parser.parse(s, new char[] { ',', ';' });
099        assertEquals("a'b'c", params.get("filename"));
100    }
101
102    @Test
103    public void testParsing() {
104        var s = "test; test1 =  stuff   ; test2 =  \"stuff; stuff\"; test3=\"stuff";
105        final var parser = new ParameterParser();
106        var params = parser.parse(s, ';');
107        assertNull(params.get("test"));
108        assertEquals("stuff", params.get("test1"));
109        assertEquals("stuff; stuff", params.get("test2"));
110        assertEquals("\"stuff", params.get("test3"));
111
112        params = parser.parse(s, new char[] { ',', ';' });
113        assertNull(params.get("test"));
114        assertEquals("stuff", params.get("test1"));
115        assertEquals("stuff; stuff", params.get("test2"));
116        assertEquals("\"stuff", params.get("test3"));
117
118        s = "  test  , test1=stuff   ,  , test2=, test3, ";
119        params = parser.parse(s, ',');
120        assertNull(params.get("test"));
121        assertEquals("stuff", params.get("test1"));
122        assertNull(params.get("test2"));
123        assertNull(params.get("test3"));
124
125        s = "  test";
126        params = parser.parse(s, ';');
127        assertNull(params.get("test"));
128
129        s = "  ";
130        params = parser.parse(s, ';');
131        assertEquals(0, params.size());
132
133        s = " = stuff ";
134        params = parser.parse(s, ';');
135        assertEquals(0, params.size());
136    }
137
138    @Test
139    public void testParsingEscapedChars() {
140        var s = "param = \"stuff\\\"; more stuff\"";
141        final var parser = new ParameterParser();
142        var params = parser.parse(s, ';');
143        assertEquals(1, params.size());
144        assertEquals("stuff\\\"; more stuff", params.get("param"));
145
146        s = "param = \"stuff\\\\\"; anotherparam";
147        params = parser.parse(s, ';');
148        assertEquals(2, params.size());
149        assertEquals("stuff\\\\", params.get("param"));
150        assertNull(params.get("anotherparam"));
151    }
152
153}