From 5683c462770a857a5244576010a97ea125e1e079 Mon Sep 17 00:00:00 2001 From: Sergey Biryukov Date: Sun, 8 Nov 2020 09:52:10 +0000 Subject: [PATCH] Site Health: Validate the test result data format in JS before using it. This will discard any invalid responses instead of causing fatal errors. It also makes badges optional, on the same basis as actions are optional. They are expected, but there may be situations where they are not present. Props Clorith, dogwithblog, kraftbj, whyisjake, SergeyBiryukov. Fixes #50145. Built from https://develop.svn.wordpress.org/trunk@49537 git-svn-id: http://core.svn.wordpress.org/trunk@49275 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/js/site-health.js | 59 ++++++++++++++++++++++++++++++++++ wp-admin/js/site-health.min.js | 2 +- wp-admin/site-health.php | 4 ++- wp-includes/version.php | 2 +- 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/wp-admin/js/site-health.js b/wp-admin/js/site-health.js index 3314f41e1e..d91b75e90a 100644 --- a/wp-admin/js/site-health.js +++ b/wp-admin/js/site-health.js @@ -65,6 +65,57 @@ jQuery( document ).ready( function( $ ) { $( this ).attr( 'aria-expanded', ! goodIssuesWrapper.hasClass( 'hidden' ) ); } ); + /** + * Validates the Site Health test result format. + * + * @since 5.6.0 + * + * @param {Object} issue + * + * @return {boolean} + */ + function validateIssueData( issue ) { + // Expected minimum format of a valid SiteHealth test response. + var minimumExpected = { + test: 'string', + label: 'string', + description: 'string' + }, + passed = true, + key, value, subKey, subValue; + + // If the issue passed is not an object, return a `false` state early. + if ( 'object' !== typeof( issue ) ) { + return false; + } + + // Loop over expected data and match the data types. + for ( key in minimumExpected ) { + value = minimumExpected[ key ]; + + if ( 'object' === typeof( value ) ) { + for ( subKey in value ) { + subValue = value[ subKey ]; + + if ( 'undefined' === typeof( issue[ key ] ) || + 'undefined' === typeof( issue[ key ][ subKey ] ) || + subValue !== typeof( issue[ key ][ subKey ] ) + ) { + passed = false; + } + } + } else { + if ( 'undefined' === typeof( issue[ key ] ) || + value !== typeof( issue[ key ] ) + ) { + passed = false; + } + } + } + + return passed; + } + /** * Appends a new issue to the issue list. * @@ -78,6 +129,14 @@ jQuery( document ).ready( function( $ ) { heading, count; + /* + * Validate the issue data format before using it. + * If the output is invalid, discard it. + */ + if ( ! validateIssueData( issue ) ) { + return false; + } + SiteHealth.site_status.issues[ issue.status ]++; count = SiteHealth.site_status.issues[ issue.status ]; diff --git a/wp-admin/js/site-health.min.js b/wp-admin/js/site-health.min.js index 1333d7a01f..18295a79da 100644 --- a/wp-admin/js/site-health.min.js +++ b/wp-admin/js/site-health.min.js @@ -1,2 +1,2 @@ /*! This file is auto-generated */ -jQuery(document).ready(function(h){var a,t,s,c=wp.i18n.__,n=wp.i18n._n,o=wp.i18n.sprintf,i=new ClipboardJS(".site-health-copy-buttons .copy-button"),d=h(".health-check-body.health-check-debug-tab").length,l=h("#health-check-accordion-block-wp-paths-sizes");function r(e){var t,s,a=wp.template("health-check-issue"),i=h("#health-check-issues-"+e.status);SiteHealth.site_status.issues[e.status]++,s=SiteHealth.site_status.issues[e.status],void 0===e.test&&(e.test=e.status+s),"critical"===e.status?t=o(n("%s critical issue","%s critical issues",s),''+s+""):"recommended"===e.status?t=o(n("%s recommended improvement","%s recommended improvements",s),''+s+""):"good"===e.status&&(t=o(n("%s item with no issues detected","%s items with no issues detected",s),''+s+"")),t&&h(".site-health-issue-count-title",i).html(t),h(".issues","#health-check-issues-"+e.status).append(a(e))}function u(){var e,t,s=h(".site-health-progress"),a=s.closest(".site-health-progress-wrapper"),i=h(".site-health-progress-label",a),n=h(".site-health-progress svg #bar"),o=parseInt(SiteHealth.site_status.issues.good,0)+parseInt(SiteHealth.site_status.issues.recommended,0)+1.5*parseInt(SiteHealth.site_status.issues.critical,0),l=.5*parseInt(SiteHealth.site_status.issues.recommended,0)+1.5*parseInt(SiteHealth.site_status.issues.critical,0),r=100-Math.ceil(l/o*100);0!==o?(a.removeClass("loading"),e=n.attr("r"),r<0&&(r=0),100"+e+"

"+t+"

",actions:""},r(wp.hooks.applyFilters("site_status_test_result",s))}i.on("success",function(e){var t=h(e.trigger),s=h(".success",t.closest("div"));e.clearSelection(),t.focus(),clearTimeout(a),s.removeClass("hidden"),a=setTimeout(function(){s.addClass("hidden"),i.clipboardAction.fakeElem&&i.clipboardAction.removeFake&&i.clipboardAction.removeFake()},3e3),wp.a11y.speak(c("Site information has been copied to your clipboard."))}),h(".health-check-accordion").on("click",".health-check-accordion-trigger",function(){"true"===h(this).attr("aria-expanded")?(h(this).attr("aria-expanded","false"),h("#"+h(this).attr("aria-controls")).attr("hidden",!0)):(h(this).attr("aria-expanded","true"),h("#"+h(this).attr("aria-controls")).attr("hidden",!1))}),h(".site-health-view-passed").on("click",function(){var e=h("#health-check-issues-good");e.toggleClass("hidden"),h(this).attr("aria-expanded",!e.hasClass("hidden"))}),"undefined"==typeof SiteHealth||d||(0===SiteHealth.site_status.direct.length&&0===SiteHealth.site_status.async.length?u():SiteHealth.site_status.issues={good:0,recommended:0,critical:0},0'+s+""):"recommended"===e.status?t=o(n("%s recommended improvement","%s recommended improvements",s),''+s+""):"good"===e.status&&(t=o(n("%s item with no issues detected","%s items with no issues detected",s),''+s+"")),t&&c(".site-health-issue-count-title",i).html(t),c(".issues","#health-check-issues-"+e.status).append(a(e))}function u(){var e,t,s=c(".site-health-progress"),a=s.closest(".site-health-progress-wrapper"),i=c(".site-health-progress-label",a),n=c(".site-health-progress svg #bar"),o=parseInt(SiteHealth.site_status.issues.good,0)+parseInt(SiteHealth.site_status.issues.recommended,0)+1.5*parseInt(SiteHealth.site_status.issues.critical,0),r=.5*parseInt(SiteHealth.site_status.issues.recommended,0)+1.5*parseInt(SiteHealth.site_status.issues.critical,0),l=100-Math.ceil(r/o*100);0!==o?(a.removeClass("loading"),e=n.attr("r"),l<0&&(l=0),100"+e+"

"+t+"

",actions:""},l(wp.hooks.applyFilters("site_status_test_result",s))}i.on("success",function(e){var t=c(e.trigger),s=c(".success",t.closest("div"));e.clearSelection(),t.focus(),clearTimeout(a),s.removeClass("hidden"),a=setTimeout(function(){s.addClass("hidden"),i.clipboardAction.fakeElem&&i.clipboardAction.removeFake&&i.clipboardAction.removeFake()},3e3),wp.a11y.speak(h("Site information has been copied to your clipboard."))}),c(".health-check-accordion").on("click",".health-check-accordion-trigger",function(){"true"===c(this).attr("aria-expanded")?(c(this).attr("aria-expanded","false"),c("#"+c(this).attr("aria-controls")).attr("hidden",!0)):(c(this).attr("aria-expanded","true"),c("#"+c(this).attr("aria-controls")).attr("hidden",!1))}),c(".site-health-view-passed").on("click",function(){var e=c("#health-check-issues-good");e.toggleClass("hidden"),c(this).attr("aria-expanded",!e.hasClass("hidden"))}),"undefined"==typeof SiteHealth||d||(0===SiteHealth.site_status.direct.length&&0===SiteHealth.site_status.async.length?u():SiteHealth.site_status.issues={good:0,recommended:0,critical:0},0 diff --git a/wp-includes/version.php b/wp-includes/version.php index d72219dedf..8a3a8d781a 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.6-beta3-49536'; +$wp_version = '5.6-beta3-49537'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.