@@ -480,6 +480,18 @@ private function formatPath(string $path): string {
480480 return $ path ;
481481 }
482482
483+ private static function checkIsArrayOfScalar (string $ name , array $ array ): void {
484+ foreach ($ array as $ item ) {
485+ if (is_array ($ item )) {
486+ self ::checkIsArrayOfScalar ($ name , $ item );
487+ } elseif ($ item !== null && !is_scalar ($ item )) {
488+ throw new DavException (
489+ "Property \"$ name \" has an invalid value of array containing " . gettype ($ item ),
490+ );
491+ }
492+ }
493+ }
494+
483495 /**
484496 * @throws ParseException If parsing a \Sabre\DAV\Xml\Property\Complex value fails
485497 * @throws DavException If the property value is invalid
@@ -514,6 +526,23 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
514526 $ valueType = self ::PROPERTY_TYPE_HREF ;
515527 $ value = $ value ->getHref ();
516528 } else {
529+ if (is_array ($ value )) {
530+ // For array only allow scalar values
531+ self ::checkIsArrayOfScalar ($ name , $ value );
532+ } elseif (!is_object ($ value )) {
533+ throw new DavException (
534+ "Property \"$ name \" has an invalid value of type " . gettype ($ value ),
535+ );
536+ } else {
537+ if (!str_starts_with ($ value ::class, 'Sabre \\DAV \\Xml \\Property \\' )
538+ && !str_starts_with ($ value ::class, 'Sabre \\CalDAV \\Xml \\Property \\' )
539+ && !str_starts_with ($ value ::class, 'Sabre \\CardDAV \\Xml \\Property \\' )
540+ && !str_starts_with ($ value ::class, 'OCA \\DAV \\' )) {
541+ throw new DavException (
542+ "Property \"$ name \" has an invalid value of class " . $ value ::class,
543+ );
544+ }
545+ }
517546 $ valueType = self ::PROPERTY_TYPE_OBJECT ;
518547 // serialize produces null character
519548 // these can not be properly stored in some databases and need to be replaced
@@ -525,20 +554,26 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
525554 /**
526555 * @return mixed|Complex|string
527556 */
528- private function decodeValueFromDatabase (string $ value , int $ valueType ) {
557+ private function decodeValueFromDatabase (string $ value , int $ valueType ): mixed {
529558 switch ($ valueType ) {
530559 case self ::PROPERTY_TYPE_XML :
531560 return new Complex ($ value );
532561 case self ::PROPERTY_TYPE_HREF :
533562 return new Href ($ value );
534563 case self ::PROPERTY_TYPE_OBJECT :
564+ if (preg_match ('/^a:/ ' , $ value )) {
565+ // Array, unserialize only scalar values
566+ return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ), ['allowed_classes ' => false ]);
567+ }
568+ if (!preg_match ('/^O\:\d+\:\"(OCA \\\\DAV \\\\|Sabre \\\\(Cal|Card)?DAV \\\\Xml \\\\Property \\\\)/ ' , $ value )) {
569+ throw new \LogicException ('Found an object class serialized in DB that is not allowed ' );
570+ }
535571 // some databases can not handel null characters, these are custom encoded during serialization
536572 // this custom encoding needs to be first reversed before unserializing
537573 return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ));
538- case self ::PROPERTY_TYPE_STRING :
539574 default :
540575 return $ value ;
541- }
576+ };
542577 }
543578
544579 private function encodeDefaultCalendarUrl (Href $ value ): Href {
0 commit comments