<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[54229] trunk: Date/Time: Correct sanitization of `timezone_string` in `sanitize_option()`.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/54229">54229</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/54229","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-09-19 23:46:26 +0000 (Mon, 19 Sep 2022)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Date/Time: Correct sanitization of `timezone_string` in `sanitize_option()`.

This fixes a bug where if the `timezone_string` is set to a timezone name which has since been deprecated, the option value would be {U+201C}lost{U+201D} when saving the value again, as the comparison being done to verify whether it is a valid timezone name would only take {U+201C}current{U+201D} timezone names into account and would invalidate deprecated timezone names.

By passing the `DateTimeZone::ALL_WITH_BC` constant as the `$timezoneGroup` parameter to the PHP native `timezone_identifiers_list()` function, a timezone name list is retrieved containing both current and deprecated timezone names, preventing the invalidation of the option value.

See the extensive write-up about this in ticket <a href="https://core.trac.wordpress.org/ticket/56468">#56468</a>.

Also see: [https://www.php.net/manual/en/datetimezone.listidentifiers.php PHP Manual: timezone_identifiers_list()].

Includes adding a dedicated test to the data provider used in the `Tests_Option_SanitizeOption` test class.

Note: The new data set is ''named'', even though the other data sets are unnamed, to make sure it is clear what this data set is testing. Adding test names for the original data sets in this data provider would be a great future improvement, but is outside of the scope of this commit.

Follow-up to <a href="https://core.trac.wordpress.org/changeset/18323">[18323]</a>, <a href="https://core.trac.wordpress.org/changeset/33119">[33119]</a>, <a href="https://core.trac.wordpress.org/changeset/54207">[54207]</a>, <a href="https://core.trac.wordpress.org/changeset/54217">[54217]</a>, <a href="https://core.trac.wordpress.org/changeset/54227">[54227]</a>.

Props jrf, costdev.
See <a href="https://core.trac.wordpress.org/ticket/56468">#56468</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesformattingphp">trunk/src/wp-includes/formatting.php</a></li>
<li><a href="#trunktestsphpunittestsoptionsanitizeOptionphp">trunk/tests/phpunit/tests/option/sanitizeOption.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesformattingphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/formatting.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/formatting.php      2022-09-19 23:32:10 UTC (rev 54228)
+++ trunk/src/wp-includes/formatting.php        2022-09-19 23:46:26 UTC (rev 54229)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -4923,7 +4923,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        break;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                case 'timezone_string':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $allowed_zones = timezone_identifiers_list();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $allowed_zones = timezone_identifiers_list( DateTimeZone::ALL_WITH_BC );
</ins><span class="cx" style="display: block; padding: 0 10px">                         if ( ! in_array( $value, $allowed_zones, true ) && ! empty( $value ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $error = __( 'The timezone you have entered is not valid. Please select a valid timezone.' );
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span></span></pre></div>
<a id="trunktestsphpunittestsoptionsanitizeOptionphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/option/sanitizeOption.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/option/sanitizeOption.php       2022-09-19 23:32:10 UTC (rev 54228)
+++ trunk/tests/phpunit/tests/option/sanitizeOption.php 2022-09-19 23:46:26 UTC (rev 54229)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -69,6 +69,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        array( 'timezone_string', 0, 0 ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array( 'timezone_string', 'Europe/London', 'Europe/London' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array( 'timezone_string', get_option( 'timezone_string' ), 'invalid' ),
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        // @ticket 56468
+                       'deprecated timezone string is accepted as valid' => array(
+                               'option_name' => 'timezone_string',
+                               'sanitized'   => 'America/Buenos_Aires',
+                               'original'    => 'America/Buenos_Aires',
+                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                         array( 'permalink_structure', '', '' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array( 'permalink_structure', '/%year%/%20%postname%', '/%year%/ %postname%' ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array( 'default_role', 'subscriber', 'subscriber' ),
</span></span></pre>
</div>
</div>

</body>
</html>