From: Michael R Sweet Date: Sun, 30 Mar 2025 23:21:30 +0000 (-0400) Subject: Fix ippDateToTime when the timezone is not GMT/UTC (Issue #1208) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29f8dbea39625dda8d7289fd457a5088893219f2;p=thirdparty%2Fcups.git Fix ippDateToTime when the timezone is not GMT/UTC (Issue #1208) --- diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index fd003a857c..6cf3e31cb9 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -194,6 +194,11 @@ AC_COMPILE_IFELSE([ AC_MSG_RESULT([no]) ]) +dnl See if we have the timegm function... +AC_CHECK_FUNC([timegm], [ + AC_DEFINE([HAVE_TIMEGM], [1], [Do we have the timegm function?]) +]) + dnl See if the stat structure has the st_gen member... AC_MSG_CHECKING([for st_gen member in stat structure]) AC_COMPILE_IFELSE([ diff --git a/config.h.in b/config.h.in index 5731867913..f54f1efc91 100644 --- a/config.h.in +++ b/config.h.in @@ -1,7 +1,7 @@ /* * Configuration file for CUPS. * - * Copyright © 2020-2024 by OpenPrinting + * Copyright © 2020-2025 by OpenPrinting * Copyright © 2007-2019 by Apple Inc. * Copyright © 1997-2007 by Easy Software Products. * @@ -316,6 +316,13 @@ #undef HAVE_TM_GMTOFF +/* + * Do we have the timegm function? + */ + +#undef HAVE_TIMEGM + + /* * Do we have getifaddrs()? */ diff --git a/configure b/configure index 0ff1950667..6f6f7fbdf2 100755 --- a/configure +++ b/configure @@ -6338,6 +6338,17 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm" +if test "x$ac_cv_func_timegm" = xyes +then : + + +printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for st_gen member in stat structure" >&5 printf %s "checking for st_gen member in stat structure... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/cups/ipp.c b/cups/ipp.c index 0df13a35f7..9c1117aba1 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1628,7 +1628,7 @@ ippDateToTime(const ipp_uchar_t *date) // I - RFC 2579 date info // 6 Seconds (0 to 60, 60 = "leap second") // 7 Deciseconds (0 to 9) // 8 +/- UTC - // 9 UTC hours (0 to 11) + // 9 UTC hours (0 to 14) // 10 UTC minutes (0 to 59) unixdate.tm_year = ((date[0] << 8) | date[1]) - 1900; unixdate.tm_mon = date[2] - 1; @@ -1637,9 +1637,24 @@ ippDateToTime(const ipp_uchar_t *date) // I - RFC 2579 date info unixdate.tm_min = date[5]; unixdate.tm_sec = date[6]; +#if _WIN32 + if ((t = _mkgmtime(&unixdate)) < 0) + return (0); +#elif defined(HAVE_TIMEGM) + if ((t = timegm(&unixdate)) < 0) + return (0); +#else if ((t = mktime(&unixdate)) < 0) return (0); +# if defined(HAVE_TM_GMTOFF) + localtime_r(&t, &unixdate); + t -= unixdate.tm_gmtoff; +# else + t -= timezone; +# endif // HAVE_TM_GMTOFF +#endif // _WIN32 + if (date[8] == '-') t += date[9] * 3600 + date[10] * 60; else diff --git a/cups/testipp.c b/cups/testipp.c index 4c255bc5e8..7ca6ea2c6a 100644 --- a/cups/testipp.c +++ b/cups/testipp.c @@ -1,7 +1,7 @@ // // IPP unit test program for libcups. // -// Copyright © 2020-2024 by OpenPrinting. +// Copyright © 2020-2025 by OpenPrinting. // Copyright © 2007-2019 by Apple Inc. // Copyright © 1997-2005 by Easy Software Products. // @@ -295,25 +295,27 @@ ssize_t write_cb(_ippdata_t *data, ipp_uchar_t *buffer, size_t bytes); // 'main()' - Main entry. // -int // O - Exit status -main(int argc, // I - Number of command-line arguments - char *argv[]) // I - Command-line arguments +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments { - _ippdata_t data; // IPP buffer - ipp_uchar_t buffer[8192]; // Write buffer data - ipp_t *cols[2], // Collections - *size; // media-size collection - ipp_t *request; // Request - ipp_attribute_t *media_col, // media-col attribute - *media_size, // media-size attribute - *attr; // Other attribute - ipp_state_t state; // State - size_t length; // Length of data - cups_file_t *fp; // File pointer - size_t i; // Looping var - int status; // Status of tests (0 = success, 1 = fail) + _ippdata_t data; // IPP buffer + ipp_uchar_t buffer[8192]; // Write buffer data + ipp_t *cols[2], // Collections + *size; // media-size collection + ipp_t *request; // Request + ipp_attribute_t *media_col, // media-col attribute + *media_size, // media-size attribute + *attr; // Other attribute + ipp_state_t state; // State + size_t length; // Length of data + cups_file_t *fp; // File pointer + size_t i; // Looping var + int status; // Status of tests (0 = success, 1 = fail) + time_t tv; // Time value + const ipp_uchar_t *dv; // Date value #ifdef DEBUG - const char *name; // Option name + const char *name; // Option name #endif // DEBUG @@ -758,6 +760,42 @@ main(int argc, // I - Number of command-line arguments testEnd(false); status = 1; } + + // Test ippDateToTime and ippTimeToDate + testBegin("ippDateToTime(1970/01/02T00:00:00Z)"); + buffer[0] = 1970 >> 8; // Year MSB + buffer[1] = 1970 & 255; // Year LSB + buffer[2] = 1; // Month + buffer[3] = 2; // Day + buffer[4] = 0; // Hour + buffer[5] = 0; // Minute + buffer[6] = 0; // Second + buffer[7] = 0; // Deci-second + buffer[8] = '+'; // Timezone +/- + buffer[9] = 0; // Timezone hours + buffer[10] = 0; // Timezone minutes + + if ((tv = ippDateToTime(buffer)) == 86400) + { + testEnd(true); + } + else + { + testEndMessage(false, "got %ld, expected 86400", (long)tv); + status = 1; + } + + testBegin("ippTimeToDate(86400)"); + + if ((dv = ippTimeToDate(86400)) != NULL && !memcmp(dv, buffer, 11)) + { + testEnd(true); + } + else + { + 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]); + status = 1; + } } else {