diff --git a/includes/activity/class-activity.php b/includes/activity/class-activity.php index 8799238..3164993 100644 --- a/includes/activity/class-activity.php +++ b/includes/activity/class-activity.php @@ -68,7 +68,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -82,7 +82,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-object-term * * @var string - * | Base_Objectr + * | Base_Object * | Link * | null */ @@ -97,7 +97,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-actor * * @var string - * | \ActivityPhp\Type\Extended\AbstractActor + * | Actor * | array * | array * | Link @@ -116,8 +116,8 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-target * * @var string - * | ObjectType - * | array + * | Base_Object + * | array * | Link * | array */ @@ -132,7 +132,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-result * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -149,7 +149,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-origin * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -162,7 +162,7 @@ class Activity extends Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-instrument * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -176,7 +176,7 @@ class Activity extends Base_Object { * * @see https://www.w3.org/TR/activitypub/#object-without-create * - * @param string|Base_Objectr|Link|null $object + * @param string|Base_Object|Link|null $object * * @return void */ diff --git a/includes/activity/class-base-object.php b/includes/activity/class-base-object.php index 3b6703b..7d81c2b 100644 --- a/includes/activity/class-base-object.php +++ b/includes/activity/class-base-object.php @@ -49,9 +49,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attachment * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -65,9 +65,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-attributedto * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -80,9 +80,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-audience * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -115,7 +115,7 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-context * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -210,9 +210,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-inreplyto * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -225,9 +225,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-location * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -239,7 +239,7 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-preview * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -287,7 +287,7 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-summary * * @var string - * | ObjectType + * | Base_Object * | Link * | null */ @@ -313,9 +313,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tag * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -348,9 +348,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-to * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -363,9 +363,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bto * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -378,9 +378,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-cc * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -393,9 +393,9 @@ class Base_Object { * @see https://www.w3.org/TR/activitystreams-vocabulary/#dfn-bcc * * @var string - * | ObjectType + * | Base_Object * | Link - * | array + * | array * | array * | null */ @@ -433,7 +433,7 @@ class Base_Object { * * @see https://www.w3.org/TR/activitypub/#source-property * - * @var ObjectType + * @var Base_Object */ protected $source; diff --git a/includes/class-sanitizer.php b/includes/class-sanitizer.php new file mode 100644 index 0000000..2deaaa2 --- /dev/null +++ b/includes/class-sanitizer.php @@ -0,0 +1,136 @@ + $value ) { + $key = self::sanitize_key( $key ); + + if ( + in_array( + $key, + array( + 'summary_map', + 'summaryMap', + 'content_map', + 'contentMap', + ), + true + ) + ) { + $sanitized_array[ $key ] = self::sanitize_map( $value ); + } elseif ( + in_array( + $key, + array( + 'inbox', + 'outbox', + 'followers', + 'following', + ), + true + ) + ) { + if ( is_string( $value ) ) { + $sanitized_array[ $key ] = sanitize_url( $value ); + } else { + $sanitized_array[ $key ] = ''; + } + } elseif ( in_array( $key, array( 'summary', 'content' ), true ) ) { + $sanitized_array[ $key ] = self::sanitize_html( $value ); + } elseif ( is_array( $value ) ) { + $sanitized_array[ $key ] = self::sanitize_array( $value ); + } else { + $sanitized_array[ $key ] = self::sanitize_value( $value ); + } + } + + return $sanitized_array; + } + + /** + * Sanitize a value. + * + * @param string $value The value to sanitize. + * + * @return string The sanitized value. + */ + public static function sanitize_value( $value ) { + if ( is_email( $value ) ) { + return sanitize_email( $value ); + } + + if ( filter_var( $value, FILTER_VALIDATE_URL ) ) { + return sanitize_url( $value ); + } + + return sanitize_text_field( $value ); + } + + /** + * Sanitize HTML. + * + * @param string $value The value to sanitize. + * + * @return string The sanitized value. + */ + public static function sanitize_html( $value ) { + if ( is_array( $value ) ) { + return ''; + } + + global $allowedtags; + $tags = array_merge( + $allowedtags, + array( 'p' => array() ) + ); + + $value = \preg_replace( '@<(script|style)[^>]*?>.*?@si', '', $value ); + $value = \strip_shortcodes( $value ); + $value = \wptexturize( $value ); + $value = \wp_kses( $value, $tags ); + + return $value; + } + + /** + * Sanitize a translation map + * + * @param array $map The map to sanitize. + * + * @return array The sanitized map. + */ + public static function sanitize_map( $map ) { + $sanitized_map = array(); + + foreach ( $map as $key => $value ) { + $key = self::sanitize_key( $key ); + + $sanitized_map[ $key ] = self::sanitize_html( $value ); + } + + return $sanitized_map; + } + + /** + * Sanitize an array key + * + * @param string $key The key to sanitize. + * + * @return string The sanitized key. + */ + public static function sanitize_key( $key ) { + return \preg_replace( '/[^a-zA-Z0-9_\-]/', '', $key ); + } +} diff --git a/tests/test-class-activitypub-sanitizer.php b/tests/test-class-activitypub-sanitizer.php new file mode 100644 index 0000000..6cfabaa --- /dev/null +++ b/tests/test-class-activitypub-sanitizer.php @@ -0,0 +1,43 @@ +assertEquals( $target, $sanitizer->sanitize_array( $source ) ); + } + + public function the_data_provider() { + return array( + array( + array( + 'type"ยง$' => '

Create

', + 'content' => '

Content

', + 'contentMap' => array( + 'en' => '

Content

', + ), + 'nameMap' => array( + 'en' => '
Content
', + ), + 'inbox' => 'https://example.org/inbox', + 'outbox' => 'example.org/outbox', + 'name' => 'Gifts\'+OR+1=1--', + ), + array( + 'type' => 'Create', + 'content' => '

Content

', + 'contentMap' => array( + 'en' => '

Content

', + ), + 'nameMap' => array( + 'en' => 'Content', + ), + 'inbox' => 'https://example.org/inbox', + 'outbox' => 'http://example.org/outbox', + 'name' => 'Gifts\'+OR+1=1--', + ), + ), + ); + } +}