View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.fileupload2.core;
    18
    19  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
    20  import static org.junit.jupiter.api.Assertions.assertThrows;
    21  import static org.junit.jupiter.api.Assertions.assertTrue;
    22  import static org.junit.jupiter.api.Assertions.fail;
    23
    24  import java.io.ByteArrayOutputStream;
    25  import java.io.IOException;
    26  import java.nio.charset.StandardCharsets;
    27
    28  import org.junit.jupiter.api.Test;
    29
    30  /**
    31   */
    32  public final class QuotedPrintableDecoderTestCase {
    33
    34      private static void assertEncoded(final String clearText, final String encoded) throws Exception {
    35          final var expected = clearText.getBytes(StandardCharsets.US_ASCII);
    36
    37          final var out = new ByteArrayOutputStream(encoded.length());
    38          final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII);
    39          QuotedPrintableDecoder.decode(encodedData, out);
    40          final var actual = out.toByteArray();
    41
    42          assertArrayEquals(expected, actual);
    43      }
    44
    45      private static void assertIOException(final String messageText, final String encoded) {
    46          final var out = new ByteArrayOutputStream(encoded.length());
    47          final var encodedData = encoded.getBytes(StandardCharsets.US_ASCII);
    48          try {
    49              QuotedPrintableDecoder.decode(encodedData, out);
    50              fail("Expected IOException");
    51          } catch (final IOException e) {
    52              final var em = e.getMessage();
    53              assertTrue(em.contains(messageText), "Expected to find " + messageText + " in '" + em + "'");
    54          }
    55      }
    56
    57      @Test
    58      public void testBasicEncodeDecode() throws Exception {
    59          assertEncoded("= Hello there =\r\n", "=3D Hello there =3D=0D=0A");
    60      }
    61
    62      @Test
    63      public void testEmptyDecode() throws Exception {
    64          assertEncoded("", "");
    65      }
    66
    67      @Test
    68      public void testInvalidCharDecode() {
    69          assertThrows(IOException.class, () -> assertEncoded("=\r\n", "=3D=XD=XA"));
    70      }
    71
    72      @Test
    73      public void testInvalidQuotedPrintableEncoding() throws Exception {
    74          assertIOException("truncated escape sequence", "YWJjMTIzXy0uKn4hQCMkJV4mKCkre31cIlxcOzpgLC9bXQ==");
    75      }
    76
    77      @Test
    78      public void testInvalidSoftBreak1() throws Exception {
    79          assertIOException("CR must be followed by LF", "=\r\r");
    80      }
    81
    82      @Test
    83      public void testInvalidSoftBreak2() throws Exception {
    84          assertIOException("CR must be followed by LF", "=\rn");
    85      }
    86
    87      @Test
    88      public void testPlainDecode() throws Exception {
    89          // spaces are allowed in encoded data
    90          // There are special rules for trailing spaces; these are not currently implemented.
    91          assertEncoded("The quick brown fox jumps over the lazy dog.", "The quick brown fox jumps over the lazy dog.");
    92      }
    93
    94      /**
    95       * This is NOT supported by Commons-Codec, see CODEC-121.
    96       *
    97       * @throws Exception
    98       * @see <a href="https://issues.apache.org/jira/browse/CODEC-121">CODEC-121</a>
    99       */
    100     @Test
    101     public void testSoftLineBreakDecode() throws Exception {
    102         assertEncoded("If you believe that truth=beauty, then surely mathematics is the most " + "beautiful branch of philosophy.",
    103                 "If you believe that truth=3Dbeauty, then " + "surely=20=\r\nmathematics is the most beautiful branch of philosophy.");
    104     }
    105
    106     @Test
    107     public void testUnsafeDecode() throws Exception {
    108         assertEncoded("=\r\n", "=3D=0D=0A");
    109     }
    110
    111     @Test
    112     public void testUnsafeDecodeLowerCase() throws Exception {
    113         assertEncoded("=\r\n", "=3d=0d=0a");
    114     }
    115
    116     @Test
    117     public void testTruncatedEscape() throws Exception {
    118         assertIOException("truncated", "=1");
    119     }
    120
    121 }