From 6e327e245b0d887f9baad6482ec951ca61f6b2bf Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Mon, 19 Dec 2016 16:04:21 +0000 Subject: [PATCH] N.497 Continuation of the fix done in [r4461], to correctly handle validation patterns containing a slash (AttributeURL in the enhanced customer portal). The initial fix has broken the validation of date (+time) fields because the slash was escaped twice, leading to an invalid regular expression. Requires testing of synchro, CSV import, console, customer portal... SVN:trunk[4538] --- core/bulkchange.class.inc.php | 4 ++-- core/datetimeformat.class.inc.php | 10 ++++++++-- synchro/synchro_import.php | 4 ++-- test/testlist.inc.php | 8 ++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/core/bulkchange.class.inc.php b/core/bulkchange.class.inc.php index 8161115e3..75a0d05b1 100644 --- a/core/bulkchange.class.inc.php +++ b/core/bulkchange.class.inc.php @@ -828,8 +828,8 @@ class BulkChange $sFormat = $sDateFormat; } $oFormat = new DateTimeFormat($sFormat); - $sRegExp = $oFormat->ToRegExpr(); - if (!preg_match('/'.$sRegExp.'/', $this->m_aData[$iRow][$iCol])) + $sRegExp = $oFormat->ToRegExpr('/'); + if (!preg_match($sRegExp, $this->m_aData[$iRow][$iCol])) { $aResult[$iRow]["__STATUS__"]= new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat')); } diff --git a/core/datetimeformat.class.inc.php b/core/datetimeformat.class.inc.php index c030c8cb5..3c4085267 100644 --- a/core/datetimeformat.class.inc.php +++ b/core/datetimeformat.class.inc.php @@ -413,10 +413,16 @@ EOF /** * Get the regular expression to (approximately) validate a date/time for the current format * The validation does not take into account the number of days in a month (i.e. June 31st will pass, as well as Feb 30th!) + * @param string $sDelimiter Surround the regexp (and escape) if needed * @return string The regular expression in PCRE syntax */ - public function ToRegExpr() + public function ToRegExpr($sDelimiter = null) { - return '^'.$this->Transform('regexpr', "\\%s", false /* escape all */, '.?*$^()[]/:').'$'; + $sRet = '^'.$this->Transform('regexpr', "\\%s", false /* escape all */, '.?*$^()[]:').'$'; + if ($sDelimiter !== null) + { + $sRet = $sDelimiter.str_replace($sDelimiter, '\\'.$sDelimiter, $sRet).$sDelimiter; + } + return $sRet; } } diff --git a/synchro/synchro_import.php b/synchro/synchro_import.php index 28492c688..f0779d9e8 100644 --- a/synchro/synchro_import.php +++ b/synchro/synchro_import.php @@ -218,8 +218,8 @@ function ChangeDateFormat($sProposedDate, $sFormat) { // Convert to a valid MySQL datetime $oFormat = new DateTimeFormat($sFormat); - $sRegExpr = $oFormat->ToRegExpr(); - if (!preg_match('/'.$sRegExpr.'/', $sProposedDate)) + $sRegExpr = $oFormat->ToRegExpr('/'); + if (!preg_match($sRegExpr, $sProposedDate)) { return false; } diff --git a/test/testlist.inc.php b/test/testlist.inc.php index 5ef8efc8b..8fa08ca55 100644 --- a/test/testlist.inc.php +++ b/test/testlist.inc.php @@ -4930,14 +4930,14 @@ class TestDateTimeFormats extends TestBizModel $oDate = new DateTime($sTestDate); $sFormattedDate = $oFormat->Format($oDate); $oParsedDate = $oFormat->Parse($sFormattedDate); - $sPattern = $oFormat->ToRegExpr(); + $sPattern = $oFormat->ToRegExpr('/'); $bParseOk = ($oParsedDate->format('Y-m-d H:i:s') == $sTestDate); if (!$bParseOk) { $this->ReportError('Parsed ('.$sFormattedDate.') date different from initial date (difference of '.((int)$oParsedDate->format('U')- (int)$oDate->format('U')).'s)'); $bRet = false; } - $bValidateOk = preg_match('/'.$sPattern.'/', $sFormattedDate); + $bValidateOk = preg_match($sPattern, $sFormattedDate); if (!$bValidateOk) { $this->ReportError('Formatted date ('.$sFormattedDate.') does not match the validation pattern ('.$sPattern.')'); @@ -4963,8 +4963,8 @@ class TestDateTimeFormats extends TestBizModel $this->ReportSuccess("Test of the '$sFormatName' format: '$sFormat':"); foreach($aDatesToParse as $sDate) { - $sPattern = $oFormat->ToRegExpr(); - $bValidateOk = preg_match('/'.$sPattern.'/', $sDate); + $sPattern = $oFormat->ToRegExpr('/'); + $bValidateOk = preg_match($sPattern, $sDate); if ($bValidateOk) { $this->ReportError('Formatted date ('.$sFormattedDate.') matches the validation pattern ('.$sPattern.') whereas it should not!');