From 09e2bf5ae199e147b55148f6aff22dba662198df Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Wed, 28 Aug 2024 11:43:35 +0000
Subject: [PATCH] fix unserialization of StudipArrayObjects, remove deprecated
 Serializable...

Closes #4537

Merge request studip/studip!3333
---
 lib/classes/StudipArrayObject.php             |  45 +-----
 .../lib/classes/StudipArrayObjectTest.php     | 131 ++++++++++++++++++
 2 files changed, 134 insertions(+), 42 deletions(-)
 create mode 100644 tests/unit/lib/classes/StudipArrayObjectTest.php

diff --git a/lib/classes/StudipArrayObject.php b/lib/classes/StudipArrayObject.php
index da7e66eb677..a93d9d39138 100644
--- a/lib/classes/StudipArrayObject.php
+++ b/lib/classes/StudipArrayObject.php
@@ -14,7 +14,7 @@
  * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  * @license   http://framework.zend.com/license/new-bsd New BSD License
  */
-class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable
+class StudipArrayObject implements IteratorAggregate, ArrayAccess, Countable
 {
     /**
      * Properties of the object have their normal functionality
@@ -147,6 +147,8 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
      */
     public function __unserialize(array $data): void
     {
+        $this->protectedProperties = array_keys(get_object_vars($this));
+
         foreach ($data as $k => $v) {
             switch ($k) {
                 case 'flag':
@@ -344,16 +346,6 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
         }
     }
 
-    /**
-     * Serialize an ArrayObject
-     *
-     * @return string
-     */
-    public function serialize()
-    {
-        return serialize(get_object_vars($this));
-    }
-
     /**
      * Sets the behavior flags
      *
@@ -417,37 +409,6 @@ class StudipArrayObject implements IteratorAggregate, ArrayAccess, Serializable,
         }
     }
 
-    /**
-     * Unserialize an ArrayObject
-     *
-     * @param  string $data
-     * @return void
-     */
-    public function unserialize($data)
-    {
-        $ar = unserialize($data);
-        $this->setFlags($ar['flag']);
-        $this->exchangeArray($ar['storage']);
-        $this->setIteratorClass($ar['iteratorClass']);
-        foreach ($ar as $k => $v) {
-            switch ($k) {
-                case 'flag':
-                    $this->setFlags($v);
-                    break;
-                case 'storage':
-                    $this->exchangeArray($v);
-                    break;
-                case 'iteratorClass':
-                    $this->setIteratorClass($v);
-                    break;
-                case 'protectedProperties':
-                    break;
-                default:
-                    $this->__set($k, $v);
-            }
-        }
-    }
-
     /**
      * Validates whether the given key is a protected property.
      *
diff --git a/tests/unit/lib/classes/StudipArrayObjectTest.php b/tests/unit/lib/classes/StudipArrayObjectTest.php
new file mode 100644
index 00000000000..aa642fb5dfb
--- /dev/null
+++ b/tests/unit/lib/classes/StudipArrayObjectTest.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * @author   Jan-Hendrik Willms <tleilax+studip@gmail.com>
+ * @license  GPL2 or any later version
+ *
+ * @covers StudipArrayObject
+ */
+class StudipArrayObjectTest extends \Codeception\Test\Unit
+{
+    /**
+     * @covers StudipArrayObject::__construct
+     */
+    public function testCreation()
+    {
+        $array = new StudipArrayObject();
+        $this->assertCount(0, $array);
+    }
+
+    /**
+     * @covers StudipArrayObject::__construct
+     */
+    public function testCreationWithData()
+    {
+        $array = new StudipArrayObject(['foo' => 'bar', 42 => 23]);
+        $this->assertCount(2, $array);
+        return $array;
+    }
+
+    /**
+     * @covers StudipArrayObject::__construct
+     */
+    public function testCreationWithInvalidIteratorClass()
+    {
+        $this->expectException(InvalidArgumentException::class);
+
+        $array = new StudipArrayObject([], StudipArrayObject::STD_PROP_LIST, 'DefinitelyNotAnIteratorClass');
+    }
+
+    /**
+     * @depends testCreationWithData
+     * @covers StudipArrayObject::offsetExists
+     * @covers StudipArrayObject::offsetGet
+     * @covers StudipArrayObject::offsetSet
+     * @covers StudipArrayObject::offsetUnset
+     */
+    public function testArrayAccess(StudipArrayObject $array)
+    {
+        $this->assertTrue(isset($array['foo']));
+        $this->assertFalse(isset($array['bar']));
+
+        $this->assertEquals('bar', $array['foo']);
+        $this->assertEquals(23, $array[42]);
+
+        $array['bar'] = 'foo';
+
+        $this->assertCount(3, $array);
+        $this->assertTrue(isset($array['bar']));
+        $this->assertEquals('foo', $array['bar']);
+
+        unset($array['bar']);
+        $this->assertCount(2, $array);
+        $this->assertFalse(isset($array['bar']));
+    }
+
+    /**
+     * @depends testCreationWithData
+     * @covers StudipArrayObject::setFlags
+     * @covers StudipArrayObject::__isset
+     * @covers StudipArrayObject::__get
+     * @covers StudipArrayObject::__set
+     * @covers StudipArrayObject::__unset
+     */
+    public function testObjectAccess(StudipArrayObject $array)
+    {
+        $array->setFlags(StudipArrayObject::ARRAY_AS_PROPS);
+
+        $this->assertTrue(isset($array->foo));
+        $this->assertFalse(isset($array->bar));
+
+        $this->assertEquals('bar', $array->foo);
+
+        $array->bar = 'foo';
+
+        $this->assertCount(3, $array);
+        $this->assertTrue(isset($array->bar));
+        $this->assertEquals('foo', $array->bar);
+
+        unset($array->bar);
+        $this->assertCount(2, $array);
+        $this->assertFalse(isset($array->bar));
+
+        $array->setFlags(StudipArrayObject::STD_PROP_LIST);
+
+        $this->expectException(InvalidArgumentException::class);
+        $test = isset($array->storage);
+    }
+
+    public function testAppend()
+    {
+        $array = new StudipArrayObject();
+        $this->assertCount(0, $array);
+
+        $array->append('foo');
+        $this->assertCount(1, $array);
+    }
+
+    public function testContains()
+    {
+        $array = new StudipArrayObject([1, 2, 3]);
+
+        $this->assertTrue($array->contains(1));
+        $this->assertFalse($array->contains(0));
+    }
+
+    public function testSerialization()
+    {
+        $array = new StudipArrayObject();
+        $array->foo = 'bar';
+
+        $serialized = serialize($array);
+        $unserialized = unserialize($serialized);
+
+        $this->assertNotFalse($unserialized);
+
+        $this->assertTrue(isset($unserialized->foo));
+        $this->assertEquals('bar', $unserialized->foo);
+
+        $this->expectException(InvalidArgumentException::class);
+        $test = isset($unserialized->storage);
+    }
+}
-- 
GitLab