@@ -571,6 +571,18 @@ private function formatPath(string $path): string {
571571 return $ path ;
572572 }
573573
574+ private static function checkIsArrayOfScalar (string $ name , array $ array ): void {
575+ foreach ($ array as $ item ) {
576+ if (is_array ($ item )) {
577+ self ::checkIsArrayOfScalar ($ name , $ item );
578+ } elseif ($ item !== null && !is_scalar ($ item )) {
579+ throw new DavException (
580+ "Property \"$ name \" has an invalid value of array containing " . gettype ($ item ),
581+ );
582+ }
583+ }
584+ }
585+
574586 /**
575587 * @throws ParseException If parsing a \Sabre\DAV\Xml\Property\Complex value fails
576588 * @throws DavException If the property value is invalid
@@ -605,6 +617,23 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
605617 $ valueType = self ::PROPERTY_TYPE_HREF ;
606618 $ value = $ value ->getHref ();
607619 } else {
620+ if (is_array ($ value )) {
621+ // For array only allow scalar values
622+ self ::checkIsArrayOfScalar ($ name , $ value );
623+ } elseif (!is_object ($ value )) {
624+ throw new DavException (
625+ "Property \"$ name \" has an invalid value of type " . gettype ($ value ),
626+ );
627+ } else {
628+ if (!str_starts_with ($ value ::class, 'Sabre \\DAV \\Xml \\Property \\' )
629+ && !str_starts_with ($ value ::class, 'Sabre \\CalDAV \\Xml \\Property \\' )
630+ && !str_starts_with ($ value ::class, 'Sabre \\CardDAV \\Xml \\Property \\' )
631+ && !str_starts_with ($ value ::class, 'OCA \\DAV \\' )) {
632+ throw new DavException (
633+ "Property \"$ name \" has an invalid value of class " . $ value ::class,
634+ );
635+ }
636+ }
608637 $ valueType = self ::PROPERTY_TYPE_OBJECT ;
609638 // serialize produces null character
610639 // these can not be properly stored in some databases and need to be replaced
@@ -616,20 +645,26 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
616645 /**
617646 * @return mixed|Complex|string
618647 */
619- private function decodeValueFromDatabase (string $ value , int $ valueType ) {
648+ private function decodeValueFromDatabase (string $ value , int $ valueType ): mixed {
620649 switch ($ valueType ) {
621650 case self ::PROPERTY_TYPE_XML :
622651 return new Complex ($ value );
623652 case self ::PROPERTY_TYPE_HREF :
624653 return new Href ($ value );
625654 case self ::PROPERTY_TYPE_OBJECT :
655+ if (preg_match ('/^a:/ ' , $ value )) {
656+ // Array, unserialize only scalar values
657+ return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ), ['allowed_classes ' => false ]);
658+ }
659+ if (!preg_match ('/^O\:\d+\:\"(OCA \\\\DAV \\\\|Sabre \\\\(Cal|Card)?DAV \\\\Xml \\\\Property \\\\)/ ' , $ value )) {
660+ throw new \LogicException ('Found an object class serialized in DB that is not allowed ' );
661+ }
626662 // some databases can not handel null characters, these are custom encoded during serialization
627663 // this custom encoding needs to be first reversed before unserializing
628664 return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ));
629- case self ::PROPERTY_TYPE_STRING :
630665 default :
631666 return $ value ;
632- }
667+ };
633668 }
634669
635670 private function encodeDefaultCalendarUrl (Href $ value ): Href {
0 commit comments