From: Markus Koschany <apo@debian.org>
Date: Wed, 22 Sep 2021 12:25:39 +0200
Subject: SecurityVulnerabilityTest

Update SecurityVulnerabilityTest.java to the latest upstream version.
---
 .../acceptance/SecurityVulnerabilityTest.java      | 95 ++++++++++++++++++----
 1 file changed, 78 insertions(+), 17 deletions(-)

diff --git a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
index 85eaf1c..d387bcd 100644
--- a/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
+++ b/xstream/src/test/com/thoughtworks/acceptance/SecurityVulnerabilityTest.java
@@ -1,21 +1,28 @@
 /*
- * Copyright (C) 2013, 2014, 2017, 2018 XStream Committers.
+ * Copyright (C) 2013, 2014, 2017, 2018, 2020, 2021 XStream Committers.
  * All rights reserved.
  *
  * The software in this package is published under the terms of the BSD
  * style license a copy of which has been included with this distribution in
  * the LICENSE.txt file.
- * 
+ *
  * Created on 23. December 2013 by Joerg Schaible
  */
 package com.thoughtworks.acceptance;
 
 import java.beans.EventHandler;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Iterator;
 
-import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.XStreamException;
 import com.thoughtworks.xstream.converters.ConversionException;
 import com.thoughtworks.xstream.converters.reflection.ReflectionConverter;
+import com.thoughtworks.xstream.security.AnyTypePermission;
 import com.thoughtworks.xstream.security.ForbiddenClassException;
 import com.thoughtworks.xstream.security.ProxyTypePermission;
 
@@ -27,6 +34,7 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
 
     private final static StringBuffer BUFFER = new StringBuffer();
 
+    @Override
     protected void setUp() throws Exception {
         super.setUp();
         BUFFER.setLength(0);
@@ -37,28 +45,26 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
 
     public void testCannotInjectEventHandler() {
         final String xml = ""
-                + "<string class='runnable-array'>\n"
-                + "  <dynamic-proxy>\n"
-                + "    <interface>java.lang.Runnable</interface>\n"
-                + "    <handler class='java.beans.EventHandler'>\n"
-                + "      <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec'/>\n"
-                + "      <action>exec</action>\n"
-                + "    </handler>\n"
-                + "  </dynamic-proxy>\n"
-                + "</string>";
+            + "<string class='runnable-array'>\n"
+            + "  <dynamic-proxy>\n"
+            + "    <interface>java.lang.Runnable</interface>\n"
+            + "    <handler class='java.beans.EventHandler'>\n"
+            + "      <target class='com.thoughtworks.acceptance.SecurityVulnerabilityTest$Exec'/>\n"
+            + "      <action>exec</action>\n"
+            + "    </handler>\n"
+            + "  </dynamic-proxy>\n"
+            + "</string>";
 
         try {
             xstream.fromXML(xml);
             fail("Thrown " + XStreamException.class.getName() + " expected");
         } catch (final XStreamException e) {
-            assertTrue(e.getMessage().indexOf(EventHandler.class.getName()) > 0);
+            assertTrue(e.getMessage().contains(EventHandler.class.getName()));
         }
         assertEquals(0, BUFFER.length());
     }
 
-    public void testCannotInjectEventHandlerWithUnconfiguredSecurityFramework() {
-        xstream = new XStream(createDriver());
-        xstream.alias("runnable", Runnable.class);
+    public void testExplicitlyConvertEventHandler() {
         final String xml = ""
             + "<string class='runnable-array'>\n"
             + "  <dynamic-proxy>\n"
@@ -76,10 +82,12 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
         } catch (final XStreamException e) {
             assertTrue(e.getMessage().indexOf(EventHandler.class.getName())>=0);
         }
+
+
         assertEquals(0, BUFFER.length());
     }
 
-    public void testExplicitlyConvertEventHandler() {
+    public void testExplicitlyConvertImageIOContainsFilter() {
         final String xml = ""
                 + "<string class='runnable-array'>\n"
                 + "  <dynamic-proxy>\n"
@@ -96,6 +104,7 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
             .getReflectionProvider(), EventHandler.class));
 
         final Runnable[] array = (Runnable[])xstream.fromXML(xml);
+
         assertEquals(0, BUFFER.length());
         array[0].run();
         assertEquals("Executed!", BUFFER.toString());
@@ -108,6 +117,15 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
         }
     }
 
+    public void testInstanceOfVoid() {
+        try {
+            xstream.fromXML("<void/>");
+            fail("Thrown " + ForbiddenClassException.class.getName() + " expected");
+        } catch (final ForbiddenClassException e) {
+            // OK
+        }
+    }
+
     public void testDeniedInstanceOfVoid() {
         try {
             xstream.fromXML("<void/>");
@@ -124,6 +142,49 @@ public class SecurityVulnerabilityTest extends AbstractAcceptanceTest {
             fail("Thrown " + ConversionException.class.getName() + " expected");
         } catch (final ConversionException e) {
             assertEquals("void", e.get("required-type"));
+
+        }
+    }
+
+    public void testCannotInjectManipulatedByteArryInputStream() {
+        xstream.alias("bais", ByteArrayInputStream.class);
+        final String xml = ""
+            + "<bais>\n"
+            + "  <buf></buf>\n"
+            + "  <pos>-2147483648</pos>\n"
+            + "  <mark>0</mark>\n"
+            + "  <count>0</count>\n"
+            + "</bais>";
+
+        try {
+            xstream.fromXML(xml);
+            fail("Thrown " + ForbiddenClassException.class.getName() + " expected");
+        } catch (final ForbiddenClassException e) {
+            assertEquals(e.getMessage(), ByteArrayInputStream.class.getName());
+        }
+    }
+
+    public void testExplicitlyUnmarshalEndlessByteArryInputStream() throws IOException {
+        xstream.alias("bais", ByteArrayInputStream.class);
+        xstream.allowTypes(new Class[]{ByteArrayInputStream.class});
+
+        final String xml = ""
+            + "<bais>\n"
+            + "  <buf></buf>\n"
+            + "  <pos>-2147483648</pos>\n"
+            + "  <mark>0</mark>\n"
+            + "  <count>0</count>\n"
+            + "</bais>";
+
+        final byte[] data = new byte[10];
+        try (final ByteArrayInputStream bais = (ByteArrayInputStream)xstream.fromXML(xml)) {
+            int i = 5;
+            while (bais.read(data, 0, 10) == 0) {
+                if (--i == 0) {
+                    break;
+                }
+            }
+            assertEquals("Unlimited reads of ByteArrayInputStream returning 0 bytes expected", 0, i);
         }
     }
 }
