[MediaWiki-commits] [Gerrit] mediawiki...Wikibase[master]: Fix (Julian)DateTimeValueCleaner for extreme years

2016-10-04 Thread jenkins-bot (Code Review)
jenkins-bot has submitted this change and it was merged.

Change subject: Fix (Julian)DateTimeValueCleaner for extreme years
..


Fix (Julian)DateTimeValueCleaner for extreme years

This fixes a series of issues, including:
* Converting years to int fails on Int32 systems.
* PHP's Julian day conversion functions return zero in many cases.

Bug: T146356
Change-Id: Ia6941a20da7e3daf232f54118aff1296bbedb1e8
---
M repo/includes/Rdf/DateTimeValueCleaner.php
M repo/includes/Rdf/JulianDateTimeValueCleaner.php
M repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
3 files changed, 40 insertions(+), 14 deletions(-)

Approvals:
  Hoo man: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/repo/includes/Rdf/DateTimeValueCleaner.php 
b/repo/includes/Rdf/DateTimeValueCleaner.php
index 45a673f..459cecc 100644
--- a/repo/includes/Rdf/DateTimeValueCleaner.php
+++ b/repo/includes/Rdf/DateTimeValueCleaner.php
@@ -86,7 +86,7 @@
// If we have year's or finer precision, to make year 
match XSD 1.1 we
// need to bump up the negative years by 1
// Note that $y is an absolute value here.
-   $y = (string)( (int)$y - 1 );
+   $y = number_format( (float)$y - 1, 0, '', '' );
if ( $y == "0" ) {
$minus = "";
}
diff --git a/repo/includes/Rdf/JulianDateTimeValueCleaner.php 
b/repo/includes/Rdf/JulianDateTimeValueCleaner.php
index b25f634..f247ec5 100644
--- a/repo/includes/Rdf/JulianDateTimeValueCleaner.php
+++ b/repo/includes/Rdf/JulianDateTimeValueCleaner.php
@@ -54,21 +54,27 @@
} catch ( IllegalValueException $e ) {
return null;
}
-   // We accept here certain precision loss since we will need to 
do calculations anyway,
-   // and we can't calculate with dates that don't fit in int.
-   $y = $minus ? -(int)$y : (int)$y;
 
-   // cal_to_jd needs int year
-   // If it's too small it's fine, we'll get 0
-   // If it's too big, it doesn't make sense anyway,
-   // since who uses Julian with day precision in year 2 billion?
-   $jd = cal_to_jd( CAL_JULIAN, $m, $d, (int)$y );
-   if ( $jd == 0 ) {
-   // that means the date is broken
-   return null;
+   $y = $minus ? -$y : $y + 0;
+   if ( !is_int( $y ) || $y < -4713 ) {
+   // Fall back to >= 1 year precision when Julian to 
Gregorian conversion is not possible.
+   return $this->cleanupGregorianValue( $dateValue, 
TimeValue::PRECISION_YEAR );
}
+
+   $jd = juliantojd( $m, $d, $y );
+   if ( $jd == 0 ) {
+   // Fall back to >= 1 year precision when Julian to 
Gregorian conversion is not possible.
+   return $this->cleanupGregorianValue( $dateValue, 
TimeValue::PRECISION_YEAR );
+   }
+
// PHP API for Julian/Gregorian conversions is kind of awful
-   list( $m, $d, $y ) = explode( '/', jdtogregorian( $jd ) );
+   $gregorian = jdtogregorian( $jd );
+   if ( $gregorian === '0/0/0' ) {
+   // Fall back to >= 1 year precision when Julian to 
Gregorian conversion is not possible.
+   return $this->cleanupGregorianValue( $dateValue, 
TimeValue::PRECISION_YEAR );
+   }
+
+   list( $m, $d, $y ) = explode( '/', $gregorian );
 
if ( $this->xsd11 && $y < 0 ) {
// To make year match XSD 1.1 we need to bump up the 
negative years by 1
diff --git a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php 
b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
index ec56642..1295ef4 100644
--- a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
+++ b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
@@ -44,13 +44,23 @@
[ '+0002204-04-31T00:00:00Z', $greg, 
'2204-04-01T00:00:00Z', $month ],
[ '+000-04-31T00:00:00Z', $greg, null ],
[ '-000-04-31T00:00:00Z', $greg, null ],
+   [ '+98765432198765-00-00T00:00:00Z', $greg, 
'98765432198765-01-01T00:00:00Z', $year ],
+   [ '-98765432198765-00-00T00:00:00Z', $greg, 
'-98765432198765-01-01T00:00:00Z', $year ],
+   [ '+-01-01T00:00:00Z', $greg, 
'-01-01T00:00:00Z' ],
+   [ '--01-01T00:00:00Z', $greg, 
'--01-01T00:00:00Z' ],
 
// Julian
[ 

[MediaWiki-commits] [Gerrit] mediawiki...Wikibase[master]: Fix (Julian)DateTimeValueCleaner for extreme years

2016-09-22 Thread WMDE
Thiemo Mättig (WMDE) has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/312215

Change subject: Fix (Julian)DateTimeValueCleaner for extreme years
..

Fix (Julian)DateTimeValueCleaner for extreme years

This fixes a series of issues, including:
* Converting years to int fails on Int32 systems.
* PHP's Julian day conversion functions return zero in many cases.

Bug: T146356
Change-Id: Ia6941a20da7e3daf232f54118aff1296bbedb1e8
---
M repo/includes/Rdf/DateTimeValueCleaner.php
M repo/includes/Rdf/JulianDateTimeValueCleaner.php
M repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
3 files changed, 29 insertions(+), 7 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/15/312215/1

diff --git a/repo/includes/Rdf/DateTimeValueCleaner.php 
b/repo/includes/Rdf/DateTimeValueCleaner.php
index 45a673f..459cecc 100644
--- a/repo/includes/Rdf/DateTimeValueCleaner.php
+++ b/repo/includes/Rdf/DateTimeValueCleaner.php
@@ -86,7 +86,7 @@
// If we have year's or finer precision, to make year 
match XSD 1.1 we
// need to bump up the negative years by 1
// Note that $y is an absolute value here.
-   $y = (string)( (int)$y - 1 );
+   $y = number_format( (float)$y - 1, 0, '', '' );
if ( $y == "0" ) {
$minus = "";
}
diff --git a/repo/includes/Rdf/JulianDateTimeValueCleaner.php 
b/repo/includes/Rdf/JulianDateTimeValueCleaner.php
index b25f634..d0060be 100644
--- a/repo/includes/Rdf/JulianDateTimeValueCleaner.php
+++ b/repo/includes/Rdf/JulianDateTimeValueCleaner.php
@@ -54,21 +54,27 @@
} catch ( IllegalValueException $e ) {
return null;
}
+
// We accept here certain precision loss since we will need to 
do calculations anyway,
// and we can't calculate with dates that don't fit in int.
$y = $minus ? -(int)$y : (int)$y;
 
// cal_to_jd needs int year
// If it's too small it's fine, we'll get 0
-   // If it's too big, it doesn't make sense anyway,
-   // since who uses Julian with day precision in year 2 billion?
$jd = cal_to_jd( CAL_JULIAN, $m, $d, (int)$y );
if ( $jd == 0 ) {
-   // that means the date is broken
-   return null;
+   // Fall back to >= 1 year precision when Julian to 
Gregorian conversion is not possible.
+   return $this->cleanupGregorianValue( $dateValue, 
TimeValue::PRECISION_YEAR );
}
+
// PHP API for Julian/Gregorian conversions is kind of awful
-   list( $m, $d, $y ) = explode( '/', jdtogregorian( $jd ) );
+   $gregorian = jdtogregorian( $jd );
+   if ( $gregorian === '0/0/0' ) {
+   // Fall back to >= 1 year precision when Julian to 
Gregorian conversion is not possible.
+   return $this->cleanupGregorianValue( $dateValue, 
TimeValue::PRECISION_YEAR );
+   }
+
+   list( $m, $d, $y ) = explode( '/', $gregorian );
 
if ( $this->xsd11 && $y < 0 ) {
// To make year match XSD 1.1 we need to bump up the 
negative years by 1
diff --git a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php 
b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
index ec56642..edb5b77 100644
--- a/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
+++ b/repo/tests/phpunit/includes/Rdf/DateTimeValueCleanerTest.php
@@ -44,13 +44,21 @@
[ '+0002204-04-31T00:00:00Z', $greg, 
'2204-04-01T00:00:00Z', $month ],
[ '+000-04-31T00:00:00Z', $greg, null ],
[ '-000-04-31T00:00:00Z', $greg, null ],
+   [ '+98765432198765-00-00T00:00:00Z', $greg, 
'98765432198765-01-01T00:00:00Z', $year ],
+   [ '-98765432198765-00-00T00:00:00Z', $greg, 
'-98765432198765-01-01T00:00:00Z', $year ],
+   [ '+-01-01T00:00:00Z', $greg, 
'-01-01T00:00:00Z' ],
+   [ '--01-01T00:00:00Z', $greg, 
'--01-01T00:00:00Z' ],
 
// Julian
[ '+0002014-01-05T12:34:56Z', $jul, 
'2014-01-18T12:34:56Z' ],
[ '-0002014-01-05T12:34:56Z', $jul, 
'-2015-12-19T12:34:56Z' ],
[ '+200-02-31T00:00:00Z', $jul, 
'0200-03-02T00:00:00Z' ],
[ '+204-02-31T00:00:00Z', $jul, 
'0204-03-02T00:00:00Z' ],
-   [