You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/07/31 19:47:49 UTC

svn commit: r1803563 - in /tomcat/trunk: java/org/apache/catalina/core/ java/org/apache/catalina/servlets/ test/org/apache/catalina/servlets/ test/webapp/bug49nnn/ webapps/docs/

Author: markt
Date: Mon Jul 31 19:47:49 2017
New Revision: 1803563

URL: http://svn.apache.org/viewvc?rev=1803563&view=rev
Log:
Re-write the unit tests for the automatic encoding conversion in the Default Servlet. The new unit tests use a parameterized approach that significantly increases the number of tests. These tests also highlighted some addition bugs that are fixed by this patch:
- Reporting the context default character encoding is now correctly treated as if no encoding has been explicitly defined
- Included resources are not converted unless an explicit encoding has been specified

Added:
    tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java   (with props)
    tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt   (with props)
    tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt   (with props)
    tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8-bom.txt   (props changed)
      - copied unchanged from r1803562, tomcat/trunk/test/webapp/bug49nnn/bug49464-utf8-bom.txt
    tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt   (with props)
Removed:
    tomcat/trunk/test/webapp/bug49nnn/bug49464-utf8-bom.txt
Modified:
    tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
    tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
    tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1803563&r1=1803562&r2=1803563&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Mon Jul 31 19:47:49 2017
@@ -834,7 +834,13 @@ public class StandardContext extends Con
 
     @Override
     public void setResponseCharacterEncoding(String responseEncoding) {
-        this.responseEncoding = responseEncoding;
+        /*
+         * This ensures that the context response encoding is represented by a
+         * unique String object. This enables the Default Servlet to
+         * differentiate between a Response using this default encoding and one
+         * that has been explicitly configured.
+         */
+        this.responseEncoding = new String(responseEncoding);
     }
 
 

Modified: tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1803563&r1=1803562&r2=1803563&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Mon Jul 31 19:47:49 2017
@@ -984,8 +984,10 @@ public class DefaultServlet extends Http
          * may have been wrapped. The != test is a (slightly hacky) quick way of
          * doing this.
          */
-        if (!usingPrecompressedVersion && isText(contentType) &&
+        boolean outputEncodingSpecified =
                 outputEncoding != org.apache.coyote.Constants.DEFAULT_BODY_CHARSET.name() &&
+                outputEncoding != resources.getContext().getResponseCharacterEncoding();
+        if (!usingPrecompressedVersion && isText(contentType) && outputEncodingSpecified &&
                 !charset.equals(fileEncodingCharset)) {
             conversionRequired = true;
             // Conversion often results fewer/more/different bytes.
@@ -1065,10 +1067,18 @@ public class DefaultServlet extends Http
                             if (bomCharset != null && useBomIfPresent) {
                                 inputEncoding = bomCharset.name();
                             }
-                            OutputStreamWriter osw = new OutputStreamWriter(ostream, charset);
-                            PrintWriter pw = new PrintWriter(osw);
-                            copy(source, pw, inputEncoding);
-                            pw.flush();
+                            // Following test also ensures included resources
+                            // are converted if an explicit output encoding was
+                            // specified
+                            if (outputEncodingSpecified) {
+                                OutputStreamWriter osw = new OutputStreamWriter(ostream, charset);
+                                PrintWriter pw = new PrintWriter(osw);
+                                copy(source, pw, inputEncoding);
+                                pw.flush();
+                            } else {
+                                // Just included but no conversion
+                                renderResult = source;
+                            }
                         } else {
                             if (!checkSendfile(request, response, resource, contentLength, null)) {
                                 // sendfile not possible so check if resource

Modified: tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java?rev=1803563&r1=1803562&r2=1803563&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java (original)
+++ tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java Mon Jul 31 19:47:49 2017
@@ -20,9 +20,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStreamWriter;
-import java.io.StringReader;
 import java.io.Writer;
-import java.nio.charset.StandardCharsets;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
@@ -31,10 +29,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.TimeZone;
 
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import static org.junit.Assert.assertEquals;
@@ -52,10 +46,8 @@ import org.apache.catalina.Wrapper;
 import org.apache.catalina.startup.SimpleHttpClient;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
-import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.buf.ByteChunk;
 import org.apache.tomcat.util.descriptor.web.ErrorPage;
-import org.apache.tomcat.util.http.parser.MediaType;
 import org.apache.tomcat.websocket.server.WsContextListener;
 
 public class TestDefaultServlet extends TomcatBaseTest {
@@ -622,205 +614,4 @@ public class TestDefaultServlet extends
             return true;
         }
     }
-
-    @Test
-    public void testEncodingIncludeIbm850StreamOutIso88591() throws Exception {
-        doTestEncodingFileIbm850(false, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeIbm850WriterOutIso88591() throws Exception {
-        doTestEncodingFileIbm850(true, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeIbm850StreamOutUtf8() throws Exception {
-        doTestEncodingFileIbm850(false, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeIbm850WriterOutUtf8() throws Exception {
-        doTestEncodingFileIbm850(true, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeIbm850StreamOutIbm850() throws Exception {
-        doTestEncodingFileIbm850(false, "IBM850");
-    }
-
-    @Test
-    public void testEncodingIncludeIbm850WriterOutIbm850() throws Exception {
-        doTestEncodingFileIbm850(false, "IBM850");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomStreamOutIso88591() throws Exception {
-        doTestEncodingFileUtf8Bom(false, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomWriterOutIso88591() throws Exception {
-        doTestEncodingFileUtf8Bom(true, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomStreamOutUtf8() throws Exception {
-        doTestEncodingFileUtf8Bom(false, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomWriterOutUtf8() throws Exception {
-        doTestEncodingFileUtf8Bom(true, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomStreamOutIbm850() throws Exception {
-        doTestEncodingFileUtf8Bom(false, "IBM850");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomWriterOutIbm850() throws Exception {
-        doTestEncodingFileUtf8Bom(false, "IBM850");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideStreamOutIso88591() throws Exception {
-        doTestEncodingFileUtf8BomOverride(false, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideWriterOutIso88591() throws Exception {
-        doTestEncodingFileUtf8BomOverride(true, "ISO-8859-1");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideStreamOutUtf8() throws Exception {
-        doTestEncodingFileUtf8BomOverride(false, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideWriterOutUtf8() throws Exception {
-        doTestEncodingFileUtf8BomOverride(true, "UTF-8");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideStreamOutIbm850() throws Exception {
-        doTestEncodingFileUtf8BomOverride(false, "IBM850");
-    }
-
-    @Test
-    public void testEncodingIncludeUtf8BomOverrideWriterOutIbm850() throws Exception {
-        doTestEncodingFileUtf8BomOverride(false, "IBM850");
-    }
-
-    private void doTestEncodingFileIbm850(boolean useWriter, String outputEncoding)
-            throws Exception {
-        doTestEncoding("/bug49nnn/bug49464-ibm850.txt", "IBM850", useWriter, outputEncoding);
-    }
-
-    private void doTestEncodingFileUtf8Bom(boolean useWriter, String outputEncoding)
-            throws Exception {
-        doTestEncoding("/bug49nnn/bug49464-utf8-bom.txt", "UTF-8", useWriter, outputEncoding);
-    }
-
-    private void doTestEncodingFileUtf8BomOverride(boolean useWriter, String outputEncoding)
-            throws Exception {
-        doTestEncoding("/bug49nnn/bug49464-utf8-bom.txt", "IBM850", useWriter, outputEncoding);
-    }
-
-    private void doTestEncoding(String includePath, String inputEncoding, boolean useWriter,
-            String outputEncoding) throws Exception {
-        Tomcat tomcat = getTomcatInstance();
-
-        File appDir = new File("test/webapp");
-
-        Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
-
-        Wrapper defaultServlet = Tomcat.addServlet(ctxt, "default", DefaultServlet.class.getName());
-        defaultServlet.addInitParameter("fileEncoding", inputEncoding);
-        ctxt.addServletMappingDecoded("/", "default");
-
-        Tomcat.addServlet(ctxt, "encoding",
-                new EncodingServlet(outputEncoding, includePath, useWriter));
-        ctxt.addServletMappingDecoded("/test", "encoding");
-
-        tomcat.start();
-
-        final ByteChunk res = new ByteChunk();
-        Map<String,List<String>> headers = new HashMap<>();
-
-        int rc = getUrl("http://localhost:" + getPort() + "/test", res, headers);
-
-        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
-        List<String> values = headers.get("Content-Type");
-        if (values.size() == 1) {
-            MediaType mediaType = MediaType.parseMediaType(new StringReader(values.get(0)));
-            String charset = mediaType.getCharset();
-            if (charset == null) {
-                res.setCharset(StandardCharsets.ISO_8859_1);
-            } else {
-                res.setCharset(B2CConverter.getCharset(charset));
-            }
-        } else {
-            res.setCharset(StandardCharsets.ISO_8859_1);
-        }
-        Assert.assertEquals("\u00bd", res.toString());
-    }
-
-    @Test
-    public void testEncodingDirect() throws Exception {
-        Tomcat tomcat = getTomcatInstance();
-
-        File appDir = new File("test/webapp");
-
-        Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
-
-        Wrapper defaultServlet = Tomcat.addServlet(ctxt, "default", DefaultServlet.class.getName());
-        defaultServlet.addInitParameter("fileEncoding", "IBM850");
-        ctxt.addServletMappingDecoded("/", "default");
-
-        tomcat.start();
-
-        final ByteChunk res = new ByteChunk();
-        Map<String,List<String>> headers = new HashMap<>();
-
-        int rc = getUrl("http://localhost:" + getPort() + "/bug49nnn/bug49464-ibm850.txt",
-                res, headers);
-
-        // This test relies on no content-type being specified in the response
-        // and the user agent correctly figuring out the content type
-        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
-        List<String> values = headers.get("Content-Type");
-        Assert.assertNull(values);
-        res.setCharset(B2CConverter.getCharset("IBM850"));
-        Assert.assertEquals("\u00bd", res.toString());
-    }
-
-    private static class EncodingServlet extends HttpServlet {
-
-        private static final long serialVersionUID = 1L;
-
-        private final String outputEncoding;
-        private final String includeTarget;
-        private final boolean useWriter;
-
-        public EncodingServlet(String outputEncoding, String includeTarget, boolean useWriter) {
-            this.outputEncoding = outputEncoding;
-            this.includeTarget = includeTarget;
-            this.useWriter = useWriter;
-        }
-
-        @Override
-        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
-                throws ServletException, IOException {
-            resp.setContentType("text/plain");
-            resp.setCharacterEncoding(outputEncoding);
-            if (useWriter) {
-                resp.getWriter();
-            }
-            resp.flushBuffer();
-            RequestDispatcher rd = req.getRequestDispatcher(includeTarget);
-            rd.include(req, resp);
-        }
-    }
 }

Added: tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java?rev=1803563&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java (added)
+++ tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java Mon Jul 31 19:47:49 2017
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.servlets;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.tomcat.util.buf.B2CConverter;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.http.parser.MediaType;
+
+@RunWith(Parameterized.class)
+public class TestDefaultServletEncoding extends TomcatBaseTest {
+
+    @Parameterized.Parameters(name = "{index}: contextEnc[{0}], fileEnc[{1}], useBom[{2}],"
+            + " target[{3}], useInclude[{4}], outputEnc[{5}], callSetCharacterEnc[{6}],"
+            + " useWriter[{7}], expectedPass[{8}]")
+    public static Collection<Object[]> parameters() {
+
+        String[] encodings = new String[] {
+                "utf-8", "ibm850", "cp1252", "iso-8859-1" };
+
+        String[] targetFiles = new String[] {
+                "cp1252", "ibm850", "iso-8859-1", "utf-8-bom", "utf-8" };
+
+        Boolean[] booleans = new Boolean[] { Boolean.FALSE, Boolean.TRUE };
+
+        List<Object[]> parameterSets = new ArrayList<>();
+
+        for (String contextResponseEncoding : encodings) {
+            for (String fileEncoding : encodings) {
+                for (Boolean useBom : booleans) {
+                    for (String targetFile : targetFiles) {
+                        for (Boolean useInclude : booleans) {
+                            if (useInclude.booleanValue()) {
+                                for (String outputEncoding : encodings) {
+                                    for (Boolean callSetCharacterEncoding : booleans) {
+                                        for (Boolean useWriter : booleans) {
+                                            Boolean expected = getExpected(fileEncoding, useBom,
+                                                    targetFile, outputEncoding,
+                                                    callSetCharacterEncoding, useWriter);
+
+                                            parameterSets.add(new Object[] {
+                                                    contextResponseEncoding, fileEncoding, useBom,
+                                                    targetFile, useInclude, outputEncoding,
+                                                    callSetCharacterEncoding, useWriter, expected
+                                            });
+                                        }
+                                    }
+                                }
+                            } else {
+                                /*
+                                 * Not using include so ignore outputEncoding,
+                                 * callSetCharacterEncoding and useWriter
+                                 *
+                                 * Tests that do not use include are always expected to
+                                 * pass.
+                                 */
+                                String encoding = targetFile;
+                                if (encoding.endsWith("-bom")) {
+                                    encoding = encoding.substring(0, encoding.length() - 4);
+                                }
+                                parameterSets.add(new Object[] { contextResponseEncoding,
+                                        fileEncoding, useBom, targetFile, useInclude, encoding,
+                                        Boolean.FALSE, Boolean.FALSE, Boolean.TRUE });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        return parameterSets;
+    }
+
+
+    private static Boolean getExpected(String fileEncoding, Boolean useBom, String targetFile,
+            String outputEncoding, Boolean callSetCharacterEncoding, Boolean useWriter) {
+        if (useWriter.booleanValue() || callSetCharacterEncoding.booleanValue()) {
+            /*
+             * Using a writer or setting the output character encoding means the
+             * response will specify a character set. These cases therefore
+             * reduce to can the file be read with the correct encoding.
+             * (Assuming any BOM is always skipped in the included output.)
+             */
+            if (targetFile.endsWith("-bom") && useBom.booleanValue() ||
+                    targetFile.startsWith(fileEncoding) ||
+                    targetFile.equals("cp1252") && fileEncoding.equals("iso-8859-1") ||
+                    targetFile.equals("iso-8859-1") && fileEncoding.equals("cp1252")) {
+                return Boolean.TRUE;
+            } else {
+                return Boolean.FALSE;
+            }
+        } else if (!(targetFile.startsWith(outputEncoding) ||
+                targetFile.equals("cp1252") && outputEncoding.equals("iso-8859-1") ||
+                targetFile.equals("iso-8859-1") && outputEncoding.equals("cp1252"))) {
+            /*
+             * The non-writer use cases read the target file as bytes. These
+             * cases therefore reduce to can the bytes from the target file be
+             * included in the output without corruption? The character used in
+             * the tests has been chosen so that, apart from iso-8859-1 and
+             * cp1252, the bytes vary by character set.
+             * (Assuming any BOM is always skipped in the included output.)
+             */
+            return Boolean.FALSE;
+        } else {
+            return Boolean.TRUE;
+        }
+    }
+
+
+    private final String contextResponseEncoding;
+    private final String fileEncoding;
+    private final boolean useBom;
+    private final String targetFile;
+    private final boolean useInclude;
+    private final String outputEncoding;
+    private final boolean callSetCharacterEncoding;
+    private final boolean useWriter;
+    private final boolean expectedPass;
+
+    public TestDefaultServletEncoding(String contextResponseEncoding, String fileEncoding,
+            boolean useBom, String targetFile, boolean useInclude, String outputEncoding,
+            boolean callSetCharacterEncoding, boolean useWriter, boolean expectedPass) {
+        this.contextResponseEncoding = contextResponseEncoding;
+        this.fileEncoding = fileEncoding;
+        this.useBom = useBom;
+        this.targetFile = targetFile;
+        this.useInclude = useInclude;
+        this.outputEncoding = outputEncoding;
+        this.callSetCharacterEncoding = callSetCharacterEncoding;
+        this.useWriter = useWriter;
+        this.expectedPass = expectedPass;
+    }
+
+    @Test
+    public void testEncoding() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+
+        File appDir = new File("test/webapp");
+        Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
+        ctxt.setResponseCharacterEncoding(contextResponseEncoding);
+        Wrapper defaultServlet = Tomcat.addServlet(ctxt, "default", DefaultServlet.class.getName());
+        defaultServlet.addInitParameter("fileEncoding", fileEncoding);
+        defaultServlet.addInitParameter("useBomIfPresent", Boolean.toString(useBom));
+
+        ctxt.addServletMappingDecoded("/", "default");
+
+        if (useInclude) {
+            Tomcat.addServlet(ctxt, "include", new EncodingServlet(
+                    outputEncoding, callSetCharacterEncoding, targetFile, useWriter));
+            ctxt.addServletMappingDecoded("/include", "include");
+        }
+
+        tomcat.start();
+
+        final ByteChunk res = new ByteChunk();
+        Map<String,List<String>> headers = new HashMap<>();
+
+        String target;
+        if (useInclude) {
+            target = "http://localhost:" + getPort() + "/include";
+        } else {
+            target = "http://localhost:" + getPort() + "/bug49nnn/bug49464-" + targetFile + ".txt";
+        }
+        int rc = getUrl(target, res, headers);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+        List<String> values = headers.get("Content-Type");
+        if (values != null && values.size() == 1) {
+            MediaType mediaType = MediaType.parseMediaType(new StringReader(values.get(0)));
+            String charset = mediaType.getCharset();
+            if (charset == null) {
+                res.setCharset(B2CConverter.getCharset(outputEncoding));
+            } else {
+                res.setCharset(B2CConverter.getCharset(charset));
+            }
+        } else {
+            res.setCharset(B2CConverter.getCharset(outputEncoding));
+        }
+        String body = res.toString();
+        /*
+         * Remove BOM before checking content
+         * BOM (should be) removed by Tomcat when file is included
+         */
+        if (!useInclude && targetFile.endsWith("-bom")) {
+            body = body.substring(1);
+        }
+
+        if (expectedPass) {
+            if (useInclude) {
+                Assert.assertEquals("\u00bd-\u00bd-\u00bd", body);
+            } else {
+                Assert.assertEquals("\u00bd", body);
+            }
+        } else {
+            if (useInclude) {
+                Assert.assertNotEquals("\u00bd-\u00bd-\u00bd", body);
+            } else {
+                Assert.assertNotEquals("\u00bd", body);
+            }
+        }
+    }
+
+
+    private static class EncodingServlet extends HttpServlet {
+
+        private static final long serialVersionUID = 1L;
+
+        private final String outputEncoding;
+        private final boolean callSetCharacterEncoding;
+        private final String includeTarget;
+        private final boolean useWriter;
+
+        public EncodingServlet(String outputEncoding, boolean callSetCharacterEncoding,
+                String includeTarget, boolean useWriter) {
+            this.outputEncoding = outputEncoding;
+            this.callSetCharacterEncoding = callSetCharacterEncoding;
+            this.includeTarget = includeTarget;
+            this.useWriter = useWriter;
+        }
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+                throws ServletException, IOException {
+            resp.setContentType("text/plain");
+            if (callSetCharacterEncoding) {
+                resp.setCharacterEncoding(outputEncoding);
+            }
+            if (useWriter) {
+                PrintWriter pw = resp.getWriter();
+                pw.print("\u00bd-");
+            } else {
+                resp.getOutputStream().write("\u00bd-".getBytes(outputEncoding));
+            }
+            resp.flushBuffer();
+            RequestDispatcher rd =
+                    req.getRequestDispatcher("/bug49nnn/bug49464-" + includeTarget + ".txt");
+            rd.include(req, resp);
+            if (useWriter) {
+                PrintWriter pw = resp.getWriter();
+                pw.print("-\u00bd");
+            } else {
+                resp.getOutputStream().write("-\u00bd".getBytes(outputEncoding));
+            }
+        }
+    }
+}

Propchange: tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServletEncoding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt?rev=1803563&view=auto
==============================================================================
--- tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt (added)
+++ tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt [cp1252] Mon Jul 31 19:47:49 2017
@@ -0,0 +1 @@
+½
\ No newline at end of file

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-cp1252.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain; charset="cp1252"

Added: tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt?rev=1803563&view=auto
==============================================================================
--- tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt (added)
+++ tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt [ISO-8859-1] Mon Jul 31 19:47:49 2017
@@ -0,0 +1 @@
+½
\ No newline at end of file

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-iso-8859-1.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain; charset="ISO-8859-1"

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8-bom.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8-bom.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain; charset="UTF-8"

Added: tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt?rev=1803563&view=auto
==============================================================================
--- tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt (added)
+++ tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt [UTF-8] Mon Jul 31 19:47:49 2017
@@ -0,0 +1 @@
+½
\ No newline at end of file

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tomcat/trunk/test/webapp/bug49nnn/bug49464-utf-8.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain; charset="UTF-8"

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1803563&r1=1803562&r2=1803563&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Mon Jul 31 19:47:49 2017
@@ -48,10 +48,8 @@
   <subsection name="Catalina">
     <changelog>
       <fix>
-        Correct another regression in the fix for <bug>49464</bug> that could
-        corrupt static content when no character encoding was explicitly defined
-        for the response and the <code>DefaultServlet</code> used a
-        <code>fileEncoding</code> that was not ISO-8859-1.(markt)
+        Correct multiple regressions in the fix for <bug>49464</bug> that could
+        corrupt static content served by the <code>DefaultServlet</code>.(markt)
       </fix>
       <fix>
         Correct a bug in the <code>PushBuilder</code> implementation that



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org