    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}