Bug 1176177

Summary: .spec file %check fails : TestTwoDigitYear
Product: Red Hat Enterprise Linux 6 Reporter: Jason Vas Dias <jason.vas.dias>
Component: icuAssignee: Eike Rathke <erack>
Status: CLOSED ERRATA QA Contact: Desktop QE <desktop-qa-list>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.7CC: tpelka
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Fixed In Version: icu-4.2.1-11.el6 Doc Type: Bug Fix
Doc Text:
Cause: 2-digit year roll-over of century in test case. Note that input of 2-digit year 34 now results in 2034 instead of 1934. Consequence: A check during build time failed. Fix: Compare the test result to next century. Result: The test case passes.
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-03-10 10:05:30 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Jason Vas Dias 2014-12-19 15:54:53 UTC
Description of problem:

Trying to rebuild icu from the srpm:
downloaded from :

(which appears to be the latest available as of writing (@ 2014/12/19)

fails, with latest tzdata-2014j-1.el6.noarch timezone data, and having
just run 'system-config-language', to create /etc/sysconfig/i18n :


I have tried running this command :

 $ rpmbuild --rebuild ${SRPMS}/icu-4.2.1-9.1.el6_2.src.rpm \
            --define _topdir' '${PWD}

with various LANG and LC_ALL settings:
 $ LC_ALL=POSIX LANG=C  rpmbuild ...
 $ LC_ALL=POSIX LANG=en_US.UTF-8  rpmbuild ...
 $ LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 rpmbuild ...

but the rpmbuild commands always fails in %check's:
      make -C source check

with the error:

Errors in total: 1.

GDB shows the expected and actual results differ:
$ cd BUILD/icu/source/test/intltest/
$ export TZ=GMT
$ LD_LIBRARY_PATH=../../lib:../../stubdata:../../tools/ctestfw  gdb --args ./intltest 

(gdb) b dtfmttst.cpp:914
Breakpoint 1 at 0x49a0d3: file dtfmttst.cpp, line 914.
(gdb) run
Breakpoint 1, DateFormatTest::TestTwoDigitYear (this=0x7fffffffcb10) at dtfmttst.cpp:914
914         UErrorCode ec = U_ZERO_ERROR;
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.4.x86_64
(gdb) n
915         SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
913     {
915         SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);
916         if (U_FAILURE(ec)) {
920         parse2DigitYear(fmt, "5/6/17", date(117, UCAL_JUNE, 5));
921         parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
(gdb) s
CalendarTimeZoneTest::date (this=0x7fffffffcb10, y=34, m=5, d=4, hr=0, min=0, sec=0) at caltztst.cpp:182
182     {
(gdb) fin
Run till exit from #0  CalendarTimeZoneTest::date (this=0x7fffffffcb10, y=34, m=5, d=4, hr=0, min=0, sec=0) at caltztst.cpp:182
0x000000000049a1f9 in DateFormatTest::TestTwoDigitYear (this=0x7fffffffcb10) at dtfmttst.cpp:921
921         parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
Value returned is $1 = -1122739200000
(gdb) s
DateFormatTest::parse2DigitYear (this=0x7fffffffcb10, fmt=..., str=0x69793b "4/6/34", expected=-1122739200000) at dtfmttst.cpp:928
928     {
(gdb) n
929         UErrorCode status = U_ZERO_ERROR;
931             UDate d = fmt.parse(str, status);
(gdb) s
icu_4_2::UnicodeString::UnicodeString (this=0x7fffffffba80, codepageData=0x69793b "4/6/34") at unistr_cnv.cpp:42
42      UnicodeString::UnicodeString(const char *codepageData)
(gdb) fin
Run till exit from #0  icu_4_2::UnicodeString::UnicodeString (this=0x7fffffffba80, codepageData=0x69793b "4/6/34") at unistr_cnv.cpp:42
0x0000000000497f55 in DateFormatTest::parse2DigitYear (this=0x7fffffffcb10, fmt=..., str=0x69793b "4/6/34", expected=-1122739200000) at dtfmttst.cpp:931
931             UDate d = fmt.parse(str, status);
(gdb) s
icu_4_2::SimpleDateFormat::parse (this=0x7fffffffbb50, text=..., status=@0x7fffffffbabc) at smpdtfmt.cpp:2155
2155        return DateFormat::parse(text, status);
(gdb) s
icu_4_2::DateFormat::parse (this=0x7fffffffbb50, text=..., status=@0x7fffffffbabc) at datefmt.cpp:207
207     {
(gdb) n
208         if (U_FAILURE(status)) return 0;
207     {
219         return result;
(gdb) p result
$2 = <value optimized out>
(gdb) fin
Run till exit from #0  icu_4_2::DateFormat::parse (this=0x7fffffffbb50, text=..., status=@0x7fffffffbabc) at datefmt.cpp:219
0x0000000000497f66 in DateFormatTest::parse2DigitYear (this=0x7fffffffcb10, fmt=..., str=0x69793b "4/6/34", expected=-1122739200000) at dtfmttst.cpp:931
931             UDate d = fmt.parse(str, status);
Value returned is $3 = 2033017200000
(gdb) info shared
From                To                  Syms Read   Shared Object Library
0x000000347b200b00  0x000000347b2198eb  Yes (*)     /lib64/ld-linux-x86-64.so.2
0x00007ffff7d73ce0  0x00007ffff7d78de8  Yes         ../../tools/ctestfw/libicutest.so.42
0x00007ffff7a38280  0x00007ffff7b1df58  Yes         ../../lib/libicui18n.so.42
0x00007ffff76c57e0  0x00007ffff7762268  Yes         ../../lib/libicuuc.so.42
0x00007ffff6540440  0x00007ffff6540548  Yes (*)     ../../lib/libicudata.so.42
0x00007ffff62fd4c0  0x00007ffff630cfe8  Yes         ../../lib/libicutu.so.42
0x000000302d605760  0x000000302d6110c8  Yes (*)     /lib64/libpthread.so.0
0x0000003038e56380  0x0000003038ec1c96  Yes         /usr/lib64/libstdc++.so.6
0x000000302ce03e70  0x000000302ce43fb8  Yes (*)     /lib64/libm.so.6
0x0000003037e028a0  0x0000003037e12da8  Yes         /lib64/libgcc_s.so.1
0x000000302ca1eaa0  0x000000302cb3ff4c  Yes (*)     /lib64/libc.so.6

Now, this is the date corresponding to time value 2033017200000 :

$ perl -MPOSIX -e 'print ctime(2033017200000);'
Fri Oct  1 16:00:00 66393

I am struggling to understand how the parser ends up with such a date
given the ASCII string "4/6/34" as input :

$ perl -MPOSIX -e '$t=mktime(0,0,0,4,5,34); print $t,": ",ctime($t);'
-1122768000: Mon Jun  4 00:00:00 1934

-1122768000 would be the correct "expected" value for the test, but the
test is expecting -1122739200000 :

$ perl -MPOSIX -e '$t=-1122739200000; print $t,": ",ctime($t);'
-1122739200000: Thu Oct 24 08:00:00 -33609

I'm confused. The 64-bit version of PERL should be producing the same
64-bit value as 'date(34, UCAL_JUNE, 4)' with TZ=GMT . The host is 
actually located in Dublin, Eire, where GMT is currently in effect .

$ ls -l /etc/localtime

lrwxrwxrwx. 1 root root 23 Jun 20 08:59 /etc/localtime -> /usr/share/zoneinfo/GMT

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
See above. Use rpmbuild to rebuild the latest icu source RPM .

Actual results:
Build fails, in 'make -C source check' .

Expected results:
Build should succeed.

Additional info:
See above.

Comment 2 Jason Vas Dias 2014-12-19 16:29:33 UTC
I think the date parser is mistakenly trying to parse the date given
default british 'MM/DD/YY', but you've supplied the US style "DD/MM/YY" :

915         SimpleDateFormat fmt("dd/MM/yy", Locale::getUK(), ec);

You should be using Locale::getUS(), because I have set :
    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8
which is the setting in /etc/sysconfig/i18n AND
in the environment of the process.

Apparently, the .spec file is not honoring settings from either 
  /etc/sysconfig/i18n or from the environment, but ONLY from 
  the host's location and is insisting that dates without centuries
  have the UK MM/dd/yy format, even though you've specified dd/MM .

I have even tried :
  $ rm /etc/localtime
  $ ln -s /usr/share/zoneinfo/EST /etc/localtime
and reconfiguring & rebuilding from scratch, but with same result.
Perhaps it is using DNS / NTP / GeoIP / keyboard to determine location ?
I use a UK keyboard layout - maybe that is it ?
Even with LANG and LC_ALL set in the environment as 'en_US.UTF-8', AND
/etc/localtime being a link to /usr/share/zoneinfo/EDT , AND with
LANG=en_US.UTF-8 in /etc/sysconfig/i18n , the test still is loading 
the Locale::getUK() locale .

Comment 3 Jason Vas Dias 2014-12-19 16:34:51 UTC
$ locale

$ LD_LIBRARY_PATH=../../lib:../../stubdata:../../tools/ctestfw  ./intltest
Errors in total: 1.
Elapsed Time: 00:00:59.000

Comment 4 Eike Rathke 2014-12-19 18:43:39 UTC
Same as bug 1106793
That darn two-digit year is now EOL..
Apply a patch similar to http://pkgs.fedoraproject.org/cgit/icu.git/commit/icu-testtwodigityear.patch?h=f21&id=3320ff38f29cb6dff40f62452ce8fc653fc89786

Comment 5 Jason Vas Dias 2015-01-05 10:47:15 UTC
With this patch applied to 4.2.1-9.1 :
diff -up source/test/intltest/dtfmttst.cpp.bz1176177 source/test/intltest/dtfmttst.cpp
--- source/test/intltest/dtfmttst.cpp.bz1176177 2009-07-01 19:50:24.000000000 +0100
+++ source/test/intltest/dtfmttst.cpp   2015-01-05 10:42:32.744004326 +0000
@@ -918,7 +918,7 @@ DateFormatTest::TestTwoDigitYear()
     parse2DigitYear(fmt, "5/6/17", date(117, UCAL_JUNE, 5));
-    parse2DigitYear(fmt, "4/6/34", date(34, UCAL_JUNE, 4));
+    parse2DigitYear(fmt, "4/6/34", date(134, UCAL_JUNE, 4));
 // -------------------------------------

all test cases pass.

Comment 9 errata-xmlrpc 2015-03-10 10:05:30 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.