diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php
index efc846b9eb..03f6e3c7b6 100644
--- a/src/wp-admin/includes/file.php
+++ b/src/wp-admin/includes/file.php
@@ -1956,17 +1956,7 @@ function wp_print_request_filesystem_credentials_modal() {
* @return string The HTML for this group and its items.
*/
function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
- $allowed_tags = array(
- 'a' => array(
- 'href' => array(),
- 'target' => array(),
- ),
- 'br' => array(),
- );
- $allowed_protocols = array( 'http', 'https' );
- $group_html = '';
-
- $group_html .= '
';
foreach ( (array) $group_data['items'] as $group_item_id => $group_item_data ) {
@@ -1975,14 +1965,14 @@ function wp_privacy_generate_personal_data_export_group_html( $group_data ) {
foreach ( (array) $group_item_data as $group_item_datum ) {
$value = $group_item_datum['value'];
- // If it looks like a link, make it a link
+ // If it looks like a link, make it a link.
if ( false === strpos( $value, ' ' ) && ( 0 === strpos( $value, 'http://' ) || 0 === strpos( $value, 'https://' ) ) ) {
$value = '
' . esc_html( $value ) . '';
}
$group_html .= '
';
$group_html .= '| ' . esc_html( $group_item_datum['name'] ) . ' | ';
- $group_html .= '' . wp_kses( $value, $allowed_tags, $allowed_protocols ) . ' | ';
+ $group_html .= '' . wp_kses( $value, 'personal_data_export' ) . ' | ';
$group_html .= '
';
}
diff --git a/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php b/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php
new file mode 100644
index 0000000000..f9f6dd5249
--- /dev/null
+++ b/tests/phpunit/tests/privacy/wpPrivacyGeneratePersonalDataExportGroupHtml.php
@@ -0,0 +1,200 @@
+ 'Test Data Group',
+ 'items' => array(
+ array(
+ array(
+ 'name' => 'Field 1 Name',
+ 'value' => 'Field 1 Value',
+ ),
+ array(
+ 'name' => 'Field 2 Name',
+ 'value' => 'Field 2 Value',
+ ),
+ ),
+ ),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+ $expected_table_markup = '
| Field 1 Name | Field 1 Value |
|---|
| Field 2 Name | Field 2 Value |
|---|
';
+
+ $this->assertContains( '
Test Data Group
', $actual );
+ $this->assertContains( $expected_table_markup, $actual );
+ }
+
+ /**
+ * Test when a multiple data items are passed.
+ *
+ * @ticket 44044
+ */
+ public function test_group_html_generation_multiple_data_items() {
+ $data = array(
+ 'group_label' => 'Test Data Group',
+ 'items' => array(
+ array(
+ array(
+ 'name' => 'Field 1 Name',
+ 'value' => 'Field 1 Value',
+ ),
+ array(
+ 'name' => 'Field 2 Name',
+ 'value' => 'Field 2 Value',
+ ),
+ ),
+ array(
+ array(
+ 'name' => 'Field 1 Name',
+ 'value' => 'Another Field 1 Value',
+ ),
+ array(
+ 'name' => 'Field 2 Name',
+ 'value' => 'Another Field 2 Value',
+ ),
+ ),
+ ),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+
+ $this->assertContains( '
Test Data Group
', $actual );
+ $this->assertContains( '
Field 1 Value', $actual );
+ $this->assertContains( ' | Another Field 1 Value', $actual );
+ $this->assertContains( ' | Field 2 Value', $actual );
+ $this->assertContains( ' | Another Field 2 Value', $actual );
+ $this->assertSame( 2, substr_count( $actual, ' | Field 1 Name' ) );
+ $this->assertSame( 2, substr_count( $actual, ' | Field 2 Name' ) );
+ $this->assertSame( 4, substr_count( $actual, ' | ' ) );
+ }
+
+ /**
+ * Values that appear to be links should be wrapped in `` tags.
+ *
+ * @ticket 44044
+ */
+ public function test_links_become_anchors() {
+ $data = array(
+ 'group_label' => 'Test Data Group',
+ 'items' => array(
+ array(
+ array(
+ 'name' => 'HTTP Link',
+ 'value' => 'http://wordpress.org',
+ ),
+ array(
+ 'name' => 'HTTPS Link',
+ 'value' => 'https://wordpress.org',
+ ),
+ array(
+ 'name' => 'Link with Spaces',
+ 'value' => 'https://wordpress.org not a link.',
+ ),
+ ),
+ ),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+
+ $this->assertContains( 'http://wordpress.org', $actual );
+ $this->assertContains( 'https://wordpress.org', $actual );
+ $this->assertContains( 'https://wordpress.org not a link.', $actual );
+ }
+
+ /**
+ * HTML in group labels should be escaped.
+ *
+ * @ticket 44044
+ */
+ public function test_group_labels_escaped() {
+ $data = array(
+ 'group_label' => 'Escape HTML in group lavels
',
+ 'items' => array(),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+
+ $this->assertContains( '<div>Escape HTML in group lavels</div>
', $actual );
+ }
+
+ /**
+ * Test that the exported data should contain allowed HTML.
+ *
+ * @ticket 44044
+ */
+ public function test_allowed_html_not_stripped() {
+ $data = array(
+ 'group_label' => 'Test Data Group',
+ 'items' => array(
+ array(
+ 'links' => array(
+ 'name' => 'Links are allowed',
+ 'value' => 'http://wordpress.org',
+ ),
+ 'formatting' => array(
+ 'name' => 'Simple formatting is allowed',
+ 'value' => 'bold, emphasis, italics, and strong are allowed.',
+ ),
+ ),
+ ),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+
+ $this->assertContains( $data['items'][0]['links']['value'], $actual );
+ $this->assertContains( $data['items'][0]['formatting']['value'], $actual );
+ }
+
+ /**
+ * Test that the exported data should not contain disallowed HTML.
+ *
+ * @ticket 44044
+ */
+ public function test_disallowed_html_is_stripped() {
+ $data = array(
+ 'group_label' => 'Test Data Group',
+ 'items' => array(
+ array(
+ 'scripts' => array(
+ 'name' => 'Script tags are not allowed.',
+ 'value' => '',
+ ),
+ 'images' => array(
+ 'name' => 'Images are not allowed',
+ 'value' => '
',
+ ),
+ ),
+ ),
+ );
+
+ $actual = wp_privacy_generate_personal_data_export_group_html( $data );
+
+ $this->assertNotContains( $data['items'][0]['scripts']['value'], $actual );
+ $this->assertContains( 'Testing that script tags are stripped. | ', $actual );
+
+ $this->assertNotContains( $data['items'][0]['images']['value'], $actual );
+ $this->assertContains( 'Images are not allowed | | ', $actual );
+ }
+}