Skip to content

Commit 211f528

Browse files
committed
Fix timezone handling in ippDateToTime, add unit tests.
1 parent b883371 commit 211f528

6 files changed

Lines changed: 89 additions & 3 deletions

File tree

CHANGES.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changes in libcups
22
==================
33

4+
libcups v3.0.0 (YYYY-MM-DD)
5+
---------------------------
6+
7+
- Fixed return values of `ippDateToTime` when the timezone isn't GMT.
8+
9+
410
libcups v3.0rc4 (2025-03-18)
511
----------------------------
612

config.h.in

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// Configuration file for libcups.
33
//
4-
// Copyright © 2020-2024 by OpenPrinting
4+
// Copyright © 2020-2025 by OpenPrinting
55
// Copyright © 2007-2019 by Apple Inc.
66
// Copyright © 1997-2007 by Easy Software Products.
77
//
@@ -144,6 +144,13 @@
144144
#undef HAVE_TM_GMTOFF
145145

146146

147+
//
148+
// Do we have the timegm function?
149+
//
150+
151+
#undef HAVE_TIMEGM
152+
153+
147154
//
148155
// Do we have hstrerror()?
149156
//

configure

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4712,6 +4712,19 @@ printf "%s\n" "no" >&6; }
47124712
fi
47134713
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
47144714

4715+
4716+
ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm"
4717+
if test "x$ac_cv_func_timegm" = xyes
4718+
then :
4719+
4720+
4721+
printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h
4722+
4723+
4724+
fi
4725+
4726+
4727+
47154728
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
47164729
printf %s "checking for long long int... " >&6; }
47174730
if test ${ac_cv_c_long_long+y}

configure.ac

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,13 @@ AC_COMPILE_IFELSE([
246246
AC_MSG_RESULT([no])
247247
])
248248

249+
250+
dnl See if we have the timegm function...
251+
AC_CHECK_FUNC([timegm], [
252+
AC_DEFINE([HAVE_TIMEGM], [1], [Do we have the timegm function?])
253+
])
254+
255+
249256
dnl Check for "long long" support...
250257
AC_CACHE_CHECK([for long long int], [ac_cv_c_long_long], [
251258
AS_IF([test "$GCC" = yes], [

cups/ipp.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1605,7 +1605,7 @@ ippDateToTime(const ipp_uchar_t *date) // I - RFC 2579 date info
16051605
// 6 Seconds (0 to 60, 60 = "leap second")
16061606
// 7 Deciseconds (0 to 9)
16071607
// 8 +/- UTC
1608-
// 9 UTC hours (0 to 11)
1608+
// 9 UTC hours (0 to 14)
16091609
// 10 UTC minutes (0 to 59)
16101610
unixdate.tm_year = ((date[0] << 8) | date[1]) - 1900;
16111611
unixdate.tm_mon = date[2] - 1;
@@ -1614,9 +1614,24 @@ ippDateToTime(const ipp_uchar_t *date) // I - RFC 2579 date info
16141614
unixdate.tm_min = date[5];
16151615
unixdate.tm_sec = date[6];
16161616

1617+
#if _WIN32
1618+
if ((t = _mkgmtime(&unixdate)) < 0)
1619+
return (0);
1620+
#elif defined(HAVE_TIMEGM)
1621+
if ((t = timegm(&unixdate)) < 0)
1622+
return (0);
1623+
#else
16171624
if ((t = mktime(&unixdate)) < 0)
16181625
return (0);
16191626

1627+
# if defined(HAVE_TM_GMTOFF)
1628+
localtime_r(&t, &unixdate);
1629+
t -= unixdate.tm_gmtoff;
1630+
# else
1631+
t -= timezone;
1632+
# endif // HAVE_TM_GMTOFF
1633+
#endif // _WIN32
1634+
16201635
if (date[8] == '-')
16211636
t += date[9] * 3600 + date[10] * 60;
16221637
else

cups/testipp.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// IPP unit test program for libcups.
33
//
4-
// Copyright © 2021-2024 by OpenPrinting.
4+
// Copyright © 2021-2025 by OpenPrinting.
55
// Copyright © 2007-2019 by Apple Inc.
66
// Copyright © 1997-2005 by Easy Software Products.
77
//
@@ -314,6 +314,8 @@ main(int argc, // I - Number of command-line arguments
314314
cups_file_t *fp; // File pointer
315315
size_t i; // Looping var
316316
int status = 0; // Status of tests (0 = success, 1 = fail)
317+
time_t tv; // Time value
318+
const ipp_uchar_t *dv; // Date value
317319
#ifdef DEBUG
318320
const char *name; // Option name
319321
#endif // DEBUG
@@ -734,6 +736,42 @@ main(int argc, // I - Number of command-line arguments
734736
// Test ippFile API...
735737
status |= test_file(/*color*/NULL);
736738
status |= test_file("blue");
739+
740+
// Test ippDateToTime and ippTimeToDate
741+
testBegin("ippDateToTime(1970/01/02T00:00:00Z)");
742+
buffer[0] = 1970 >> 8; // Year MSB
743+
buffer[1] = 1970 & 255; // Year LSB
744+
buffer[2] = 1; // Month
745+
buffer[3] = 2; // Day
746+
buffer[4] = 0; // Hour
747+
buffer[5] = 0; // Minute
748+
buffer[6] = 0; // Second
749+
buffer[7] = 0; // Deci-second
750+
buffer[8] = '+'; // Timezone +/-
751+
buffer[9] = 0; // Timezone hours
752+
buffer[10] = 0; // Timezone minutes
753+
754+
if ((tv = ippDateToTime(buffer)) == 86400)
755+
{
756+
testEnd(true);
757+
}
758+
else
759+
{
760+
testEndMessage(false, "got %ld, expected 86400", (long)tv);
761+
status = 1;
762+
}
763+
764+
testBegin("ippTimeToDate(86400)");
765+
766+
if ((dv = ippTimeToDate(86400)) != NULL && !memcmp(dv, buffer, 11))
767+
{
768+
testEnd(true);
769+
}
770+
else
771+
{
772+
testEndMessage(false, "got %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X, expected %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", dv[0], dv[1], dv[2], dv[3], dv[4], dv[5], dv[6], dv[7], dv[8], dv[9], dv[10], buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], buffer[8], buffer[9], buffer[10]);
773+
status = 1;
774+
}
737775
}
738776
else
739777
{

0 commit comments

Comments
 (0)