This is an automated email from the git hooks/post-receive script.

apo-guest pushed a commit to branch master
in repository libspring-java.

commit a8fbd23b3048058d221c01004ff187262d6c5a7b
Author: Markus Koschany <a...@gambaru.de>
Date:   Fri Jan 24 18:00:09 2014 +0100

    Fix CVE-2013-6429 CVE-2013-6430.
---
 debian/changelog                   |  18 +
 debian/patches/CVE-2013-6429.patch | 712 +++++++++++++++++++++++++++++++++++++
 debian/patches/CVE-2013-6430.patch | 151 ++++++++
 debian/patches/series              |   2 +
 4 files changed, 883 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index b2876ce..4883ed5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
+libspring-java (3.0.6.RELEASE-11) unstable; urgency=high
+
+  * Team upload.
+  * Fix CVE-2013-6429 and CVE-2013-6430. (Closes: #735420)
+    - New patches: CVE-2013-6429.patch and CVE-2013-6430.patch.
+    - Spring MVC's SourceHttpMessageConverter also processed user provided XML
+      and neither disabled XML external entities nor provided an option to
+      disable them. SourceHttpMessageConverter has been modified to provide an
+      option to control the processing of XML external entities and that
+      processing is now disabled by default.
+    - The JavaScriptUtils.javaScriptEscape() method did not escape all
+      characters that are sensitive within either a JS single quoted string, JS
+      double quoted string, or HTML script data context. In most cases this
+      will result in an unexploitable parse error but in some cases it could
+      result in an XSS vulnerability.
+
+ -- Markus Koschany <a...@gambaru.de>  Fri, 24 Jan 2014 19:22:14 +0100
+
 libspring-java (3.0.6.RELEASE-10) unstable; urgency=high
 
   * Team upload.
diff --git a/debian/patches/CVE-2013-6429.patch 
b/debian/patches/CVE-2013-6429.patch
new file mode 100644
index 0000000..3334c0e
--- /dev/null
+++ b/debian/patches/CVE-2013-6429.patch
@@ -0,0 +1,712 @@
+From: Markus Koschany <a...@gambaru.de>
+Date: Fri, 24 Jan 2014 16:46:07 +0100
+Subject: CVE-2013-6429
+
+Bug: http://bugs.debian.org/735420
+---
+ .../java/org/springframework/util/StreamUtils.java | 183 ++++++++++++++++++++
+ .../org/springframework/util/xml/StaxUtils.java    |  15 +-
+ .../converter/xml/SourceHttpMessageConverter.java  | 190 +++++++++++++++++----
+ .../xml/SourceHttpMessageConverterTests.java       | 145 +++++++++++++---
+ .../http/converter/xml/external.txt                |   1 +
+ 5 files changed, 478 insertions(+), 56 deletions(-)
+ create mode 100644 
projects/org.springframework.core/src/main/java/org/springframework/util/StreamUtils.java
+ create mode 100644 
projects/org.springframework.web/src/test/resources/org/springframework/http/converter/xml/external.txt
+
+diff --git 
a/projects/org.springframework.core/src/main/java/org/springframework/util/StreamUtils.java
 
b/projects/org.springframework.core/src/main/java/org/springframework/util/StreamUtils.java
+new file mode 100644
+index 0000000..cc3107d
+--- /dev/null
++++ 
b/projects/org.springframework.core/src/main/java/org/springframework/util/StreamUtils.java
+@@ -0,0 +1,183 @@
++/*
++ * Copyright 2002-2013 the original author or authors.
++ *
++ * Licensed 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.springframework.util;
++
++import java.io.ByteArrayOutputStream;
++import java.io.FilterInputStream;
++import java.io.FilterOutputStream;
++import java.io.IOException;
++import java.io.InputStream;
++import java.io.InputStreamReader;
++import java.io.OutputStream;
++import java.io.OutputStreamWriter;
++import java.io.Writer;
++import java.nio.charset.Charset;
++
++
++/**
++ * Simple utility methods for dealing with streams. The copy methods of this 
class are
++ * similar to those defined in {@link FileCopyUtils} except that all affected 
streams are
++ * left open when done. All copy methods use a block size of 4096 bytes.
++ *
++ * <p>Mainly for use within the framework, but also useful for application 
code.
++ *
++ * @author Juergen Hoeller
++ * @author Phillip Webb
++ * @since 3.2.2
++ * @see FileCopyUtils
++ */
++public abstract class StreamUtils {
++
++      public static final int BUFFER_SIZE = 4096;
++
++
++      /**
++       * Copy the contents of the given InputStream into a new byte array.
++       * Leaves the stream open when done.
++       * @param in the stream to copy from
++       * @return the new byte array that has been copied to
++       * @throws IOException in case of I/O errors
++       */
++      public static byte[] copyToByteArray(InputStream in) throws IOException 
{
++              ByteArrayOutputStream out = new 
ByteArrayOutputStream(BUFFER_SIZE);
++              copy(in, out);
++              return out.toByteArray();
++      }
++
++      /**
++       * Copy the contents of the given InputStream into a String.
++       * Leaves the stream open when done.
++       * @param in the InputStream to copy from
++       * @return the String that has been copied to
++       * @throws IOException in case of I/O errors
++       */
++      public static String copyToString(InputStream in, Charset charset) 
throws IOException {
++              Assert.notNull(in, "No InputStream specified");
++              StringBuilder out = new StringBuilder();
++              InputStreamReader reader = new InputStreamReader(in, charset);
++              char[] buffer = new char[BUFFER_SIZE];
++              int bytesRead = -1;
++              while ((bytesRead = reader.read(buffer)) != -1) {
++                      out.append(buffer, 0, bytesRead);
++              }
++              return out.toString();
++      }
++
++      /**
++       * Copy the contents of the given byte array to the given OutputStream.
++       * Leaves the stream open when done.
++       * @param in the byte array to copy from
++       * @param out the OutputStream to copy to
++       * @throws IOException in case of I/O errors
++       */
++      public static void copy(byte[] in, OutputStream out) throws IOException 
{
++              Assert.notNull(in, "No input byte array specified");
++              Assert.notNull(out, "No OutputStream specified");
++              out.write(in);
++      }
++
++      /**
++       * Copy the contents of the given String to the given output 
OutputStream.
++       * Leaves the stream open when done.
++       * @param in the String to copy from
++       * @param charset the Charset
++       * @param out the OutputStream to copy to
++       * @throws IOException in case of I/O errors
++       */
++      public static void copy(String in, Charset charset, OutputStream out) 
throws IOException {
++              Assert.notNull(in, "No input String specified");
++              Assert.notNull(charset, "No charset specified");
++              Assert.notNull(out, "No OutputStream specified");
++              Writer writer = new OutputStreamWriter(out, charset);
++              writer.write(in);
++              writer.flush();
++      }
++
++      /**
++       * Copy the contents of the given InputStream to the given OutputStream.
++       * Leaves both streams open when done.
++       * @param in the InputStream to copy from
++       * @param out the OutputStream to copy to
++       * @return the number of bytes copied
++       * @throws IOException in case of I/O errors
++       */
++      public static int copy(InputStream in, OutputStream out) throws 
IOException {
++              Assert.notNull(in, "No InputStream specified");
++              Assert.notNull(out, "No OutputStream specified");
++              int byteCount = 0;
++              byte[] buffer = new byte[BUFFER_SIZE];
++              int bytesRead = -1;
++              while ((bytesRead = in.read(buffer)) != -1) {
++                      out.write(buffer, 0, bytesRead);
++                      byteCount += bytesRead;
++              }
++              out.flush();
++              return byteCount;
++      }
++
++      /**
++       * Returns a variant of the given {@link InputStream} where calling
++       * {@link InputStream#close() close()} has no effect.
++       * @param in the InputStream to decorate
++       * @return a version of the InputStream that ignores calls to close
++       */
++      public static InputStream nonClosing(InputStream in) {
++              Assert.notNull(in, "No InputStream specified");
++              return new NonClosingInputStream(in);
++      }
++
++      /**
++       * Returns a variant of the given {@link OutputStream} where calling
++       * {@link OutputStream#close() close()} has no effect.
++       * @param out the OutputStream to decorate
++       * @return a version of the OutputStream that ignores calls to close
++       */
++      public static OutputStream nonClosing(OutputStream out) {
++              Assert.notNull(out, "No OutputStream specified");
++              return new NonClosingOutputStream(out);
++      }
++
++
++      private static class NonClosingInputStream extends FilterInputStream {
++
++              public NonClosingInputStream(InputStream in) {
++                      super(in);
++              }
++
++              @Override
++              public void close() throws IOException {
++              }
++      }
++
++
++      private static class NonClosingOutputStream extends FilterOutputStream {
++
++              public NonClosingOutputStream(OutputStream out) {
++                      super(out);
++              }
++
++              @Override
++              public void write(byte[] b, int off, int let) throws 
IOException {
++                      // It is critical that we override this method for 
performance
++                      out.write(b, off, let);
++              }
++
++              @Override
++              public void close() throws IOException {
++              }
++      }
++}
+diff --git 
a/projects/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
 
b/projects/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
+index 4bd4a7a..dee73ca 100644
+--- 
a/projects/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
++++ 
b/projects/org.springframework.core/src/main/java/org/springframework/util/xml/StaxUtils.java
+@@ -113,7 +113,16 @@ public abstract class StaxUtils {
+        * 1.4 {@link StAXSource}; {@code false} otherwise.
+        */
+       public static boolean isStaxSource(Source source) {
+-              return (source instanceof StaxSource || (jaxp14Available && 
Jaxp14StaxHandler.isStaxSource(source)));
++              return ((source instanceof StaxSource) || (jaxp14Available && 
Jaxp14StaxHandler.isStaxSource(source)));
++      }
++
++      /**
++       * Indicate whether the given class is a StAX Source class.
++       * @return {@code true} if {@code source} is a custom StAX source or 
JAXP
++       * 1.4 {@link StAXSource} class; {@code false} otherwise.
++       */
++      public static boolean isStaxSourceClass(Class<? extends Source> clazz) {
++              return (StaxSource.class.equals(clazz) || (jaxp14Available && 
Jaxp14StaxHandler.isStaxSourceClass(clazz)));
+       }
+ 
+       // Stax Result
+@@ -343,6 +352,10 @@ public abstract class StaxUtils {
+                       return source instanceof StAXSource;
+               }
+ 
++              private static boolean isStaxSourceClass(Class<? extends 
Source> clazz) {
++            return StAXSource.class.equals(clazz);
++        }
++
+               private static boolean isStaxResult(Result result) {
+                       return result instanceof StAXResult;
+               }
+diff --git 
a/projects/org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java
 
b/projects/org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java
+index 4ba1aac..15b7d8e 100644
+--- 
a/projects/org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java
++++ 
b/projects/org.springframework.web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2002-2010 the original author or authors.
++ * Copyright 2002-2013 the original author or authors.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+@@ -19,21 +19,40 @@ package org.springframework.http.converter.xml;
+ import java.io.ByteArrayInputStream;
+ import java.io.ByteArrayOutputStream;
+ import java.io.IOException;
++import java.io.InputStream;
++import java.io.OutputStream;
++import javax.xml.parsers.DocumentBuilder;
++import javax.xml.parsers.DocumentBuilderFactory;
++import javax.xml.parsers.ParserConfigurationException;
++import javax.xml.stream.XMLInputFactory;
++import javax.xml.stream.XMLStreamException;
++import javax.xml.stream.XMLStreamReader;
+ import javax.xml.transform.Result;
+ import javax.xml.transform.Source;
+ import javax.xml.transform.TransformerException;
++import javax.xml.transform.TransformerFactory;
+ import javax.xml.transform.dom.DOMResult;
+ import javax.xml.transform.dom.DOMSource;
+ import javax.xml.transform.sax.SAXSource;
+ import javax.xml.transform.stream.StreamResult;
+ import javax.xml.transform.stream.StreamSource;
+ 
++import org.w3c.dom.Document;
+ import org.xml.sax.InputSource;
++import org.xml.sax.SAXException;
++import org.xml.sax.XMLReader;
++import org.xml.sax.helpers.XMLReaderFactory;
+ 
+ import org.springframework.http.HttpHeaders;
++import org.springframework.http.HttpInputMessage;
++import org.springframework.http.HttpOutputMessage;
++import org.springframework.http.MediaType;
++import org.springframework.http.converter.AbstractHttpMessageConverter;
+ import org.springframework.http.converter.HttpMessageConversionException;
+ import org.springframework.http.converter.HttpMessageNotReadableException;
+ import org.springframework.http.converter.HttpMessageNotWritableException;
++import org.springframework.util.StreamUtils;
++import org.springframework.util.xml.StaxUtils;
+ 
+ /**
+  * Implementation of {@link 
org.springframework.http.converter.HttpMessageConverter}
+@@ -42,55 +61,154 @@ import 
org.springframework.http.converter.HttpMessageNotWritableException;
+  * @author Arjen Poutsma
+  * @since 3.0
+  */
+-public class SourceHttpMessageConverter<T extends Source> extends 
AbstractXmlHttpMessageConverter<T> {
++public class SourceHttpMessageConverter<T extends Source> extends 
AbstractHttpMessageConverter<T> {
+ 
+-      @Override
++    private final TransformerFactory transformerFactory = 
TransformerFactory.newInstance();
++
++    private boolean processExternalEntities = false;
++
++    /**
++     * Sets the {@link #setSupportedMediaTypes(java.util.List) 
supportedMediaTypes}
++     * to {@code text/xml} and {@code application/xml}, and {@code 
application/*-xml}.
++     */
++    public SourceHttpMessageConverter() {
++        super(MediaType.APPLICATION_XML, MediaType.TEXT_XML, new 
MediaType("application", "*+xml"));
++    }
++
++
++    /**
++     * Indicates whether external XML entities are processed when converting
++     * to a Source.
++     * <p>Default is {@code false}, meaning that external entities are not 
resolved.
++     */
++    public void setProcessExternalEntities(boolean processExternalEntities) {
++        this.processExternalEntities = processExternalEntities;
++    }
++
++    @Override
+       public boolean supports(Class<?> clazz) {
+-              return DOMSource.class.equals(clazz) || 
SAXSource.class.equals(clazz) || StreamSource.class.equals(clazz) ||
+-                              Source.class.equals(clazz);
++              return DOMSource.class.equals(clazz) || 
SAXSource.class.equals(clazz)
++                              || StreamSource.class.equals(clazz) || 
Source.class.equals(clazz);
+       }
+ 
++    @Override
++    protected T readInternal(Class<? extends T> clazz, HttpInputMessage 
inputMessage)
++            throws IOException, HttpMessageNotReadableException {
++
++        InputStream body = inputMessage.getBody();
++        if (DOMSource.class.equals(clazz)) {
++            return (T) readDOMSource(body);
++        }
++        else if (StaxUtils.isStaxSourceClass(clazz)) {
++            return (T) readStAXSource(body);
++        }
++        else if (SAXSource.class.equals(clazz)) {
++            return (T) readSAXSource(body);
++        }
++        else if (StreamSource.class.equals(clazz) || 
Source.class.equals(clazz)) {
++            return (T) readStreamSource(body);
++        }
++        else {
++            throw new HttpMessageConversionException("Could not read class [" 
+ clazz +
++                    "]. Only DOMSource, SAXSource, and StreamSource are 
supported.");
++        }
++    }
++
++    private DOMSource readDOMSource(InputStream body) throws IOException {
++        try {
++            DocumentBuilderFactory documentBuilderFactory = 
DocumentBuilderFactory.newInstance();
++            documentBuilderFactory.setNamespaceAware(true);
++            
documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities";,
 processExternalEntities);
++            DocumentBuilder documentBuilder = 
documentBuilderFactory.newDocumentBuilder();
++            Document document = documentBuilder.parse(body);
++            return new DOMSource(document);
++        }
++        catch (ParserConfigurationException ex) {
++            throw new HttpMessageNotReadableException("Could not set feature: 
" + ex.getMessage(), ex);
++        }
++        catch (SAXException ex) {
++            throw new HttpMessageNotReadableException("Could not parse 
document: " + ex.getMessage(), ex);
++        }
++    }
++
++    private SAXSource readSAXSource(InputStream body) throws IOException {
++        try {
++            XMLReader reader = XMLReaderFactory.createXMLReader();
++            
reader.setFeature("http://xml.org/sax/features/external-general-entities";, 
processExternalEntities);
++            byte[] bytes = StreamUtils.copyToByteArray(body);
++            return new SAXSource(reader, new InputSource(new 
ByteArrayInputStream(bytes)));
++        }
++        catch (SAXException ex) {
++            throw new HttpMessageNotReadableException("Could not parse 
document: " + ex.getMessage(), ex);
++        }
++    }
++
++    private Source readStAXSource(InputStream body) {
++        try {
++            XMLInputFactory inputFactory = XMLInputFactory.newFactory();
++            
inputFactory.setProperty("javax.xml.stream.isSupportingExternalEntities", 
processExternalEntities);
++            XMLStreamReader streamReader = 
inputFactory.createXMLStreamReader(body);
++            return StaxUtils.createStaxSource(streamReader);
++        }
++        catch (XMLStreamException ex) {
++            throw new HttpMessageNotReadableException("Could not parse 
document: " + ex.getMessage(), ex);
++        }
++    }
++
++    private StreamSource readStreamSource(InputStream body) throws 
IOException {
++        byte[] bytes = StreamUtils.copyToByteArray(body);
++        return new StreamSource(new ByteArrayInputStream(bytes));
++    }
++
+       @Override
+-      @SuppressWarnings("unchecked")
+-      protected T readFromSource(Class clazz, HttpHeaders headers, Source 
source) throws IOException {
+-              try {
+-                      if (DOMSource.class.equals(clazz)) {
+-                              DOMResult domResult = new DOMResult();
+-                              transform(source, domResult);
+-                              return (T) new DOMSource(domResult.getNode());
+-                      }
+-                      else if (SAXSource.class.equals(clazz)) {
+-                              ByteArrayInputStream bis = 
transformToByteArrayInputStream(source);
+-                              return (T) new SAXSource(new InputSource(bis));
++      protected Long getContentLength(T t, MediaType contentType) {
++              if (t instanceof DOMSource) {
++                      try {
++                              CountingOutputStream os = new 
CountingOutputStream();
++                              transform(t, new StreamResult(os));
++                              return os.count;
+                       }
+-                      else if (StreamSource.class.equals(clazz) || 
Source.class.equals(clazz)) {
+-                              ByteArrayInputStream bis = 
transformToByteArrayInputStream(source);
+-                              return (T) new StreamSource(bis);
+-                      }
+-                      else {
+-                              throw new HttpMessageConversionException("Could 
not read class [" + clazz +
+-                                              "]. Only DOMSource, SAXSource, 
and StreamSource are supported.");
++                      catch (TransformerException ex) {
++                              // ignore
+                       }
+               }
+-              catch (TransformerException ex) {
+-                      throw new HttpMessageNotReadableException("Could not 
transform from [" + source + "] to [" + clazz + "]",
+-                                      ex);
+-              }
+-      }
+-
+-      private ByteArrayInputStream transformToByteArrayInputStream(Source 
source) throws TransformerException {
+-              ByteArrayOutputStream bos = new ByteArrayOutputStream();
+-              transform(source, new StreamResult(bos));
+-              return new ByteArrayInputStream(bos.toByteArray());
++              return null;
+       }
+ 
+-      @Override
+-      protected void writeToResult(T t, HttpHeaders headers, Result result) 
throws IOException {
++    @Override
++    protected void writeInternal(T t, HttpOutputMessage outputMessage)
++            throws IOException, HttpMessageNotWritableException {
+               try {
++            Result result = new StreamResult(outputMessage.getBody());
+                       transform(t, result);
+               }
+               catch (TransformerException ex) {
+-                      throw new HttpMessageNotWritableException("Could not 
transform [" + t + "] to [" + result + "]", ex);
++                      throw new HttpMessageNotWritableException("Could not 
transform [" + t + "] to output message", ex);
++              }
++      }
++
++    private void transform(Source source, Result result) throws 
TransformerException {
++        this.transformerFactory.newTransformer().transform(source, result);
++    }
++
++
++    private static class CountingOutputStream extends OutputStream {
++
++              private long count = 0;
++
++              @Override
++              public void write(int b) throws IOException {
++                      count++;
++              }
++
++              @Override
++              public void write(byte[] b) throws IOException {
++                      count += b.length;
++              }
++
++              @Override
++              public void write(byte[] b, int off, int len) throws 
IOException {
++                      count += len;
+               }
+       }
+ 
+diff --git 
a/projects/org.springframework.web/src/test/java/org/springframework/http/converter/xml/SourceHttpMessageConverterTests.java
 
b/projects/org.springframework.web/src/test/java/org/springframework/http/converter/xml/SourceHttpMessageConverterTests.java
+index bb20f8a..8d47c22 100644
+--- 
a/projects/org.springframework.web/src/test/java/org/springframework/http/converter/xml/SourceHttpMessageConverterTests.java
++++ 
b/projects/org.springframework.web/src/test/java/org/springframework/http/converter/xml/SourceHttpMessageConverterTests.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2002-2010 the original author or authors.
++ * Copyright 2002-2013 the original author or authors.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+@@ -16,35 +16,60 @@
+ 
+ package org.springframework.http.converter.xml;
+ 
++import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual;
++import static org.junit.Assert.*;
++import static org.junit.Assert.assertNotEquals;
++
++import java.io.IOException;
++import java.io.InputStream;
+ import java.io.InputStreamReader;
++import java.io.StringReader;
+ import java.nio.charset.Charset;
++
+ import javax.xml.parsers.DocumentBuilderFactory;
++import javax.xml.stream.XMLStreamException;
++import javax.xml.stream.XMLStreamReader;
+ import javax.xml.transform.Source;
+ import javax.xml.transform.dom.DOMSource;
+ import javax.xml.transform.sax.SAXSource;
++import javax.xml.transform.stax.StAXSource;
+ import javax.xml.transform.stream.StreamSource;
+ 
+-import static org.custommonkey.xmlunit.XMLAssert.*;
+ import org.junit.Before;
+ import org.junit.Test;
+-import org.w3c.dom.Document;
+-import org.w3c.dom.Element;
+-import org.xml.sax.InputSource;
+ 
++import org.springframework.core.io.ClassPathResource;
++import org.springframework.core.io.Resource;
+ import org.springframework.http.MediaType;
+ import org.springframework.http.MockHttpInputMessage;
+ import org.springframework.http.MockHttpOutputMessage;
+ import org.springframework.util.FileCopyUtils;
++import org.w3c.dom.Document;
++import org.w3c.dom.Element;
++import org.xml.sax.InputSource;
++import org.xml.sax.SAXException;
++import org.xml.sax.XMLReader;
++import org.xml.sax.helpers.DefaultHandler;
+ 
+-/** @author Arjen Poutsma */
+-@SuppressWarnings("unchecked")
++/**
++ * @author Arjen Poutsma
++ */
+ public class SourceHttpMessageConverterTests {
+ 
++      private static final String BODY = "<root>Hello World</root>";
++
+       private SourceHttpMessageConverter<Source> converter;
+ 
++      private String bodyExternal;
++
+       @Before
+-      public void setUp() {
++      public void setUp() throws IOException {
+               converter = new SourceHttpMessageConverter<Source>();
++              Resource external = new ClassPathResource("external.txt", 
getClass());
++
++              bodyExternal = "<!DOCTYPE root [" +
++                              "  <!ELEMENT root ANY >\n" +
++                              "  <!ENTITY ext SYSTEM \"" + external.getURI() 
+ "\" >]><root>&ext;</root>";
+       }
+ 
+       @Test
+@@ -62,45 +87,100 @@ public class SourceHttpMessageConverterTests {
+ 
+       @Test
+       public void readDOMSource() throws Exception {
+-              String body = "<root>Hello World</root>";
+-              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(body.getBytes("UTF-8"));
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(BODY.getBytes("UTF-8"));
++              inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
++              DOMSource result = (DOMSource) converter.read(DOMSource.class, 
inputMessage);
++              Document document = (Document) result.getNode();
++              assertEquals("Invalid result", "root", 
document.getDocumentElement().getLocalName());
++      }
++
++      @Test
++      public void readDOMSourceExternal() throws Exception {
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
+               inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
+               DOMSource result = (DOMSource) converter.read(DOMSource.class, 
inputMessage);
+               Document document = (Document) result.getNode();
+               assertEquals("Invalid result", "root", 
document.getDocumentElement().getLocalName());
++              assertNotEquals("Invalid result", "Foo Bar", 
document.getDocumentElement().getTextContent());
+       }
+ 
+       @Test
+       public void readSAXSource() throws Exception {
+-              String body = "<root>Hello World</root>";
+-              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(body.getBytes("UTF-8"));
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(BODY.getBytes("UTF-8"));
+               inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
+               SAXSource result = (SAXSource) converter.read(SAXSource.class, 
inputMessage);
+               InputSource inputSource = result.getInputSource();
+               String s = FileCopyUtils.copyToString(new 
InputStreamReader(inputSource.getByteStream()));
+-              assertXMLEqual("Invalid result", body, s);
++              assertXMLEqual("Invalid result", BODY, s);
+       }
+ 
+       @Test
++      public void readSAXSourceExternal() throws Exception {
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
++              inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
++              SAXSource result = (SAXSource) converter.read(SAXSource.class, 
inputMessage);
++              InputSource inputSource = result.getInputSource();
++              XMLReader reader = result.getXMLReader();
++              reader.setContentHandler(new DefaultHandler() {
++                      @Override
++                      public void characters(char[] ch, int start, int 
length) throws SAXException {
++                              String s = new String(ch, start, length);
++                              assertNotEquals("Invalid result", "Foo Bar", s);
++                      }
++              });
++              reader.parse(inputSource);
++      }
++
++      @Test
++      public void readStAXSource() throws Exception {
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(BODY.getBytes("UTF-8"));
++              inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
++              StAXSource result = (StAXSource) 
converter.read(StAXSource.class, inputMessage);
++              XMLStreamReader streamReader = result.getXMLStreamReader();
++              assertTrue(streamReader.hasNext());
++              streamReader.nextTag();
++              String s = streamReader.getLocalName();
++              assertEquals("root", s);
++              s = streamReader.getElementText();
++              assertEquals("Hello World", s);
++              streamReader.close();
++      }
++
++      @Test
++      public void readStAXSourceExternal() throws Exception {
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
++              inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
++              StAXSource result = (StAXSource) 
converter.read(StAXSource.class, inputMessage);
++              XMLStreamReader streamReader = result.getXMLStreamReader();
++              assertTrue(streamReader.hasNext());
++              streamReader.next();
++              streamReader.next();
++              String s = streamReader.getLocalName();
++              assertEquals("root", s);
++              s = streamReader.getElementText();
++              assertNotEquals("Foo Bar", s);
++              streamReader.close();
++      }
++
++
++      @Test
+       public void readStreamSource() throws Exception {
+-              String body = "<root>Hello World</root>";
+-              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(body.getBytes("UTF-8"));
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(BODY.getBytes("UTF-8"));
+               inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
+               StreamSource result = (StreamSource) 
converter.read(StreamSource.class, inputMessage);
+               String s = FileCopyUtils.copyToString(new 
InputStreamReader(result.getInputStream()));
+-              assertXMLEqual("Invalid result", body, s);
++              assertXMLEqual("Invalid result", BODY, s);
+       }
+ 
+       @Test
+       public void readSource() throws Exception {
+-              String body = "<root>Hello World</root>";
+-              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(body.getBytes("UTF-8"));
++              MockHttpInputMessage inputMessage = new 
MockHttpInputMessage(BODY.getBytes("UTF-8"));
+               inputMessage.getHeaders().setContentType(new 
MediaType("application", "xml"));
+               converter.read(Source.class, inputMessage);
+       }
+ 
+       @Test
+-      public void write() throws Exception {
++      public void writeDOMSource() throws Exception {
+               DocumentBuilderFactory documentBuilderFactory = 
DocumentBuilderFactory.newInstance();
+               documentBuilderFactory.setNamespaceAware(true);
+               Document document = 
documentBuilderFactory.newDocumentBuilder().newDocument();
+@@ -115,7 +195,34 @@ public class SourceHttpMessageConverterTests {
+                               
outputMessage.getBodyAsString(Charset.forName("UTF-8")));
+               assertEquals("Invalid content-type", new 
MediaType("application", "xml"),
+                               outputMessage.getHeaders().getContentType());
++              assertEquals("Invalid content-length", 
outputMessage.getBodyAsBytes().length,
++                              outputMessage.getHeaders().getContentLength());
+       }
+ 
++      @Test
++      public void writeSAXSource() throws Exception {
++              String xml = "<root>Hello World</root>";
++              SAXSource saxSource = new SAXSource(new InputSource(new 
StringReader(xml)));
++
++              MockHttpOutputMessage outputMessage = new 
MockHttpOutputMessage();
++              converter.write(saxSource, null, outputMessage);
++              assertXMLEqual("Invalid result", "<root>Hello World</root>",
++                              
outputMessage.getBodyAsString(Charset.forName("UTF-8")));
++              assertEquals("Invalid content-type", new 
MediaType("application", "xml"),
++                              outputMessage.getHeaders().getContentType());
++      }
++
++      @Test
++      public void writeStreamSource() throws Exception {
++              String xml = "<root>Hello World</root>";
++              StreamSource streamSource = new StreamSource(new 
StringReader(xml));
++
++              MockHttpOutputMessage outputMessage = new 
MockHttpOutputMessage();
++              converter.write(streamSource, null, outputMessage);
++              assertXMLEqual("Invalid result", "<root>Hello World</root>",
++                              
outputMessage.getBodyAsString(Charset.forName("UTF-8")));
++              assertEquals("Invalid content-type", new 
MediaType("application", "xml"),
++                              outputMessage.getHeaders().getContentType());
++      }
+ 
+ }
+diff --git 
a/projects/org.springframework.web/src/test/resources/org/springframework/http/converter/xml/external.txt
 
b/projects/org.springframework.web/src/test/resources/org/springframework/http/converter/xml/external.txt
+new file mode 100644
+index 0000000..76c7ac2
+--- /dev/null
++++ 
b/projects/org.springframework.web/src/test/resources/org/springframework/http/converter/xml/external.txt
+@@ -0,0 +1 @@
++Foo Bar
diff --git a/debian/patches/CVE-2013-6430.patch 
b/debian/patches/CVE-2013-6430.patch
new file mode 100644
index 0000000..7c4c362
--- /dev/null
+++ b/debian/patches/CVE-2013-6430.patch
@@ -0,0 +1,151 @@
+From: Markus Koschany <a...@gambaru.de>
+Date: Thu, 23 Jan 2014 00:03:13 +0100
+Subject: CVE-2013-6430
+
+Bug: http://bugs.debian.org/735420
+---
+ .../springframework/web/util/JavaScriptUtils.java  | 35 ++++++++---
+ .../web/util/JavaScriptUtilsTests.java             | 67 ++++++++++++++++++++++
+ 2 files changed, 95 insertions(+), 7 deletions(-)
+ create mode 100644 
projects/org.springframework.web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
+
+diff --git 
a/projects/org.springframework.web/src/main/java/org/springframework/web/util/JavaScriptUtils.java
 
b/projects/org.springframework.web/src/main/java/org/springframework/web/util/JavaScriptUtils.java
+index b28d398..861b46f 100644
+--- 
a/projects/org.springframework.web/src/main/java/org/springframework/web/util/JavaScriptUtils.java
++++ 
b/projects/org.springframework.web/src/main/java/org/springframework/web/util/JavaScriptUtils.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2002-2008 the original author or authors.
++ * Copyright 2002-2013 the original author or authors.
+  *
+  * Licensed under the Apache License, Version 2.0 (the "License");
+  * you may not use this file except in compliance with the License.
+@@ -21,21 +21,21 @@ package org.springframework.web.util;
+  * Escapes based on the JavaScript 1.5 recommendation.
+  *
+  * <p>Reference:
+- * <a 
href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Literals#String_Literals";>
+- * Core JavaScript 1.5 Guide
+- * </a>
++ * <a 
href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#String_literals";>
++ * JavaScript Guide</a> on Mozilla Developer Network.
+  *
+  * @author Juergen Hoeller
+  * @author Rob Harrop
++ * @author Rossen Stoyanchev
+  * @since 1.1.1
+  */
+ public class JavaScriptUtils {
+ 
+       /**
+-       * Turn special characters into escaped characters conforming to 
JavaScript.
+-       * Handles complete character set defined in HTML 4.01 recommendation.
++       * Turn JavaScript special characters into escaped characters.
++       *
+        * @param input the input string
+-       * @return the escaped string
++       * @return the string with escaped characters
+        */
+       public static String javaScriptEscape(String input) {
+               if (input == null) {
+@@ -73,6 +73,27 @@ public class JavaScriptUtils {
+                       else if (c == '\f') {
+                               filtered.append("\\f");
+                       }
++                      else if (c == '\b') {
++                              filtered.append("\\b");
++                      }
++                      // No '\v' in Java, use octal value for VT ascii char
++                      else if (c == '\013') {
++                              filtered.append("\\v");
++                      }
++                      else if (c == '<') {
++                              filtered.append("\\u003C");
++                      }
++                      else if (c == '>') {
++                              filtered.append("\\u003E");
++                      }
++                      // Unicode for PS (line terminator in ECMA-262)
++                      else if (c == '\u2028') {
++                              filtered.append("\\u2028");
++                      }
++                      // Unicode for LS (line terminator in ECMA-262)
++                      else if (c == '\u2029') {
++                              filtered.append("\\u2029");
++                      }
+                       else {
+                               filtered.append(c);
+                       }
+diff --git 
a/projects/org.springframework.web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
 
b/projects/org.springframework.web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
+new file mode 100644
+index 0000000..182f18e
+--- /dev/null
++++ 
b/projects/org.springframework.web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
+@@ -0,0 +1,67 @@
++/*
++ * Copyright 2004-2013 the original author or authors.
++ *
++ * Licensed 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.springframework.web.util;
++
++import static org.junit.Assert.*;
++
++import java.io.UnsupportedEncodingException;
++
++import org.junit.Test;
++
++/**
++ * Test fixture for {@link JavaScriptUtils}.
++ *
++ * @author Rossen Stoyanchev
++ */
++public class JavaScriptUtilsTests {
++
++      @Test
++      public void escape() {
++              StringBuilder sb = new StringBuilder();
++              sb.append('"');
++              sb.append("'");
++              sb.append("\\");
++              sb.append("/");
++              sb.append("\t");
++              sb.append("\n");
++              sb.append("\r");
++              sb.append("\f");
++              sb.append("\b");
++              sb.append("\013");
++              assertEquals("\\\"\\'\\\\\\/\\t\\n\\n\\f\\b\\v", 
JavaScriptUtils.javaScriptEscape(sb.toString()));
++      }
++
++      // SPR-9983
++
++      @Test
++      public void escapePsLsLineTerminators() {
++              StringBuilder sb = new StringBuilder();
++              sb.append('\u2028');
++              sb.append('\u2029');
++              String result = JavaScriptUtils.javaScriptEscape(sb.toString());
++
++              assertEquals("\\u2028\\u2029", result);
++      }
++
++      // SPR-9983
++
++      @Test
++      public void escapeLessThanGreaterThanSigns() throws 
UnsupportedEncodingException {
++              assertEquals("\\u003C\\u003E", 
JavaScriptUtils.javaScriptEscape("<>"));
++      }
++
++}
diff --git a/debian/patches/series b/debian/patches/series
index 533ec80..c989a84 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -10,3 +10,5 @@
 0010_velocity_17.diff
 0011-java7-compat.patch
 Add-processExternalEntities-to-JAXB2Marshaller.patch
+CVE-2013-6429.patch
+CVE-2013-6430.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-java/libspring-java.git

_______________________________________________
pkg-java-commits mailing list
pkg-java-commits@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

Reply via email to