@@ -531,6 +531,18 @@ private function formatPath(string $path): string {
531531 return $ path ;
532532 }
533533
534+ private static function checkIsArrayOfScalar (string $ name , array $ array ): void {
535+ foreach ($ array as $ item ) {
536+ if (is_array ($ item )) {
537+ self ::checkIsArrayOfScalar ($ name , $ item );
538+ } elseif ($ item !== null && !is_scalar ($ item )) {
539+ throw new DavException (
540+ "Property \"$ name \" has an invalid value of array containing " . gettype ($ item ),
541+ );
542+ }
543+ }
544+ }
545+
534546 /**
535547 * @throws ParseException If parsing a \Sabre\DAV\Xml\Property\Complex value fails
536548 * @throws DavException If the property value is invalid
@@ -565,6 +577,23 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
565577 $ valueType = self ::PROPERTY_TYPE_HREF ;
566578 $ value = $ value ->getHref ();
567579 } else {
580+ if (is_array ($ value )) {
581+ // For array only allow scalar values
582+ self ::checkIsArrayOfScalar ($ name , $ value );
583+ } elseif (!is_object ($ value )) {
584+ throw new DavException (
585+ "Property \"$ name \" has an invalid value of type " . gettype ($ value ),
586+ );
587+ } else {
588+ if (!str_starts_with ($ value ::class, 'Sabre \\DAV \\Xml \\Property \\' )
589+ && !str_starts_with ($ value ::class, 'Sabre \\CalDAV \\Xml \\Property \\' )
590+ && !str_starts_with ($ value ::class, 'Sabre \\CardDAV \\Xml \\Property \\' )
591+ && !str_starts_with ($ value ::class, 'OCA \\DAV \\' )) {
592+ throw new DavException (
593+ "Property \"$ name \" has an invalid value of class " . $ value ::class,
594+ );
595+ }
596+ }
568597 $ valueType = self ::PROPERTY_TYPE_OBJECT ;
569598 // serialize produces null character
570599 // these can not be properly stored in some databases and need to be replaced
@@ -576,20 +605,26 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value
576605 /**
577606 * @return mixed|Complex|string
578607 */
579- private function decodeValueFromDatabase (string $ value , int $ valueType ) {
608+ private function decodeValueFromDatabase (string $ value , int $ valueType ): mixed {
580609 switch ($ valueType ) {
581610 case self ::PROPERTY_TYPE_XML :
582611 return new Complex ($ value );
583612 case self ::PROPERTY_TYPE_HREF :
584613 return new Href ($ value );
585614 case self ::PROPERTY_TYPE_OBJECT :
615+ if (preg_match ('/^a:/ ' , $ value )) {
616+ // Array, unserialize only scalar values
617+ return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ), ['allowed_classes ' => false ]);
618+ }
619+ if (!preg_match ('/^O\:\d+\:\"(OCA \\\\DAV \\\\|Sabre \\\\(Cal|Card)?DAV \\\\Xml \\\\Property \\\\)/ ' , $ value )) {
620+ throw new \LogicException ('Found an object class serialized in DB that is not allowed ' );
621+ }
586622 // some databases can not handel null characters, these are custom encoded during serialization
587623 // this custom encoding needs to be first reversed before unserializing
588624 return unserialize (str_replace ('\x00 ' , chr (0 ), $ value ));
589- case self ::PROPERTY_TYPE_STRING :
590625 default :
591626 return $ value ;
592- }
627+ };
593628 }
594629
595630 private function encodeDefaultCalendarUrl (Href $ value ): Href {
0 commit comments