mirror of
https://github.com/michaelrsweet/pdfio.git
synced 2025-04-05 16:36:44 +02:00
Update date/time parsing (Issue #115)
This commit is contained in:
parent
b8ea9ea064
commit
8cca645835
@ -5,6 +5,7 @@ Changes in PDFio
|
||||
v1.5.2 - YYYY-MM-DD
|
||||
-------------------
|
||||
|
||||
- Fixed parsing of certain date/time values (Issue #115)
|
||||
- Fixed support for empty name values (Issue #116)
|
||||
|
||||
|
||||
|
203
configure
vendored
203
configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for pdfio 1.5.1.
|
||||
# Generated by GNU Autoconf 2.71 for pdfio 1.5.2.
|
||||
#
|
||||
# Report bugs to <https://github.com/michaelrsweet/pdfio/issues>.
|
||||
#
|
||||
@ -610,8 +610,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='pdfio'
|
||||
PACKAGE_TARNAME='pdfio'
|
||||
PACKAGE_VERSION='1.5.1'
|
||||
PACKAGE_STRING='pdfio 1.5.1'
|
||||
PACKAGE_VERSION='1.5.2'
|
||||
PACKAGE_STRING='pdfio 1.5.2'
|
||||
PACKAGE_BUGREPORT='https://github.com/michaelrsweet/pdfio/issues'
|
||||
PACKAGE_URL='https://www.msweet.org/pdfio'
|
||||
|
||||
@ -1295,7 +1295,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures pdfio 1.5.1 to adapt to many kinds of systems.
|
||||
\`configure' configures pdfio 1.5.2 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1361,7 +1361,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of pdfio 1.5.1:";;
|
||||
short | recursive ) echo "Configuration of pdfio 1.5.2:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1460,7 +1460,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
pdfio configure 1.5.1
|
||||
pdfio configure 1.5.2
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@ -1513,39 +1513,6 @@ fi
|
||||
|
||||
} # ac_fn_c_try_compile
|
||||
|
||||
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
|
||||
# -------------------------------------------------------
|
||||
# Tests whether HEADER exists and can be compiled using the include files in
|
||||
# INCLUDES, setting the cache variable VAR accordingly.
|
||||
ac_fn_c_check_header_compile ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
printf %s "checking for $2... " >&6; }
|
||||
if eval test \${$3+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
#include <$2>
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
eval "$3=yes"
|
||||
else $as_nop
|
||||
eval "$3=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_c_check_header_compile
|
||||
|
||||
# ac_fn_c_try_link LINENO
|
||||
# -----------------------
|
||||
# Try to link conftest.$ac_ext, and return whether this succeeded.
|
||||
@ -1592,6 +1559,101 @@ fi
|
||||
as_fn_set_status $ac_retval
|
||||
|
||||
} # ac_fn_c_try_link
|
||||
|
||||
# ac_fn_c_check_func LINENO FUNC VAR
|
||||
# ----------------------------------
|
||||
# Tests whether FUNC exists, setting the cache variable VAR accordingly
|
||||
ac_fn_c_check_func ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
printf %s "checking for $2... " >&6; }
|
||||
if eval test \${$3+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
|
||||
For example, HP-UX 11i <limits.h> declares gettimeofday. */
|
||||
#define $2 innocuous_$2
|
||||
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $2 (); below. */
|
||||
|
||||
#include <limits.h>
|
||||
#undef $2
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char $2 ();
|
||||
/* The GNU C library defines this for functions which it implements
|
||||
to always fail with ENOSYS. Some functions are actually named
|
||||
something starting with __ and the normal name is an alias. */
|
||||
#if defined __stub_$2 || defined __stub___$2
|
||||
choke me
|
||||
#endif
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return $2 ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
eval "$3=yes"
|
||||
else $as_nop
|
||||
eval "$3=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_c_check_func
|
||||
|
||||
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
|
||||
# -------------------------------------------------------
|
||||
# Tests whether HEADER exists and can be compiled using the include files in
|
||||
# INCLUDES, setting the cache variable VAR accordingly.
|
||||
ac_fn_c_check_header_compile ()
|
||||
{
|
||||
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
|
||||
printf %s "checking for $2... " >&6; }
|
||||
if eval test \${$3+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$4
|
||||
#include <$2>
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
eval "$3=yes"
|
||||
else $as_nop
|
||||
eval "$3=no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
fi
|
||||
eval ac_res=\$$3
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
|
||||
printf "%s\n" "$ac_res" >&6; }
|
||||
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
|
||||
|
||||
} # ac_fn_c_check_header_compile
|
||||
ac_configure_args_raw=
|
||||
for ac_arg
|
||||
do
|
||||
@ -1616,7 +1678,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by pdfio $as_me 1.5.1, which was
|
||||
It was created by pdfio $as_me 1.5.2, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@ -2372,9 +2434,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
PDFIO_VERSION="1.5.1"
|
||||
PDFIO_VERSION_MAJOR="`echo 1.5.1 | awk -F. '{print $1}'`"
|
||||
PDFIO_VERSION_MINOR="`echo 1.5.1 | awk -F. '{printf("%d\n",$2);}'`"
|
||||
PDFIO_VERSION="1.5.2"
|
||||
PDFIO_VERSION_MAJOR="`echo 1.5.2 | awk -F. '{print $1}'`"
|
||||
PDFIO_VERSION_MINOR="`echo 1.5.2 | awk -F. '{printf("%d\n",$2);}'`"
|
||||
|
||||
|
||||
|
||||
@ -3877,6 +3939,56 @@ INSTALL="$(pwd)/install-sh"
|
||||
printf "%s\n" "using $INSTALL" >&6; }
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
CPPFLAGS="-DHAVE_TIMEGM=1 $CPPFLAGS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tm_gmtoff member in tm structure" >&5
|
||||
printf %s "checking for tm_gmtoff member in tm structure... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <time.h>
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
struct tm t;
|
||||
int o = t.tm_gmtoff;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
printf "%s\n" "#define HAVE_TM_GMTOFF 1" >>confdefs.h
|
||||
|
||||
CPPFLAGS="-DHAVE_TM_GMTOFF=1 $CPPFLAGS"
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
|
||||
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
|
||||
@ -3998,7 +4110,6 @@ PKGCONFIG_REQUIRES="zlib"
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlib via pkg-config" >&5
|
||||
printf %s "checking for zlib via pkg-config... " >&6; }
|
||||
|
||||
ac_header= ac_cache=
|
||||
for ac_item in $ac_header_c_list
|
||||
do
|
||||
@ -4988,7 +5099,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by pdfio $as_me 1.5.1, which was
|
||||
This file was extended by pdfio $as_me 1.5.2, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -5044,7 +5155,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
pdfio config.status 1.5.1
|
||||
pdfio config.status 1.5.2
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
23
configure.ac
23
configure.ac
@ -21,7 +21,7 @@ AC_PREREQ([2.70])
|
||||
|
||||
|
||||
dnl Package name and version...
|
||||
AC_INIT([pdfio], [1.5.1], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
||||
AC_INIT([pdfio], [1.5.2], [https://github.com/michaelrsweet/pdfio/issues], [pdfio], [https://www.msweet.org/pdfio])
|
||||
|
||||
PDFIO_VERSION="AC_PACKAGE_VERSION"
|
||||
PDFIO_VERSION_MAJOR="`echo AC_PACKAGE_VERSION | awk -F. '{print $1}'`"
|
||||
@ -88,6 +88,27 @@ AC_SUBST([INSTALL])
|
||||
AC_MSG_RESULT([using $INSTALL])
|
||||
|
||||
|
||||
dnl Check for date/time functionality...
|
||||
AC_CHECK_FUNC([timegm], [
|
||||
AC_DEFINE([HAVE_TIMEGM], [1], [Do we have the timegm function?])
|
||||
CPPFLAGS="-DHAVE_TIMEGM=1 $CPPFLAGS"
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([for tm_gmtoff member in tm structure])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[#include <time.h>]], [[
|
||||
struct tm t;
|
||||
int o = t.tm_gmtoff;
|
||||
]])
|
||||
], [
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_DEFINE([HAVE_TM_GMTOFF], [1], [Have tm_gmtoff member in struct tm?])
|
||||
CPPFLAGS="-DHAVE_TM_GMTOFF=1 $CPPFLAGS"
|
||||
], [
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
|
||||
|
||||
dnl Check for pkg-config, which is used for some other tests later on...
|
||||
AC_PATH_TOOL([PKGCONFIG], [pkg-config])
|
||||
|
||||
|
@ -351,7 +351,7 @@ _pdfioValueRead(pdfio_file_t *pdf, // I - PDF file
|
||||
if ((v->value.dict = _pdfioDictRead(pdf, obj, tb, depth + 1)) == NULL)
|
||||
return (NULL);
|
||||
}
|
||||
else if (!strncmp(token, "(D:", 3) && (timeval = get_date_time(token + 1)) != 0)
|
||||
else if ((timeval = get_date_time(token + 1)) != 0)
|
||||
{
|
||||
v->type = PDFIO_VALTYPE_DATE;
|
||||
v->value.date = timeval;
|
||||
@ -707,31 +707,59 @@ _pdfioValueWrite(pdfio_file_t *pdf, // I - PDF file
|
||||
// 'get_date_time()' - Convert PDF date/time value to time_t.
|
||||
//
|
||||
|
||||
static time_t // O - Time in seconds
|
||||
static time_t // O - Time in seconds or `0` for none
|
||||
get_date_time(const char *s) // I - PDF date/time value
|
||||
{
|
||||
int i; // Looping var
|
||||
struct tm dateval; // Date value
|
||||
int offset; // Date offset
|
||||
int offset = 0; // Date offset in seconds
|
||||
time_t t; // Time value
|
||||
|
||||
|
||||
PDFIO_DEBUG("get_date_time(s=\"%s\")\n", s);
|
||||
|
||||
// Possible date value of the form:
|
||||
//
|
||||
// (D:YYYYMMDDhhmmssZ)
|
||||
// (D:YYYYMMDDhhmmss+HH'mm)
|
||||
// (D:YYYYMMDDhhmmss-HH'mm)
|
||||
// D:YYYYMMDDhhmmssZ
|
||||
// D:YYYYMMDDhhmmss+HH'mm
|
||||
// D:YYYYMMDDhhmmss-HH'mm
|
||||
//
|
||||
|
||||
if (strncmp(s, "D:", 2))
|
||||
return (0);
|
||||
|
||||
for (i = 2; i < 16; i ++)
|
||||
{
|
||||
// Look for date/time digits...
|
||||
if (!isdigit(s[i] & 255) || !s[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= 16)
|
||||
if (i < 6 || (i & 1))
|
||||
{
|
||||
// Short year or missing digit...
|
||||
return (0);
|
||||
}
|
||||
|
||||
memset(&dateval, 0, sizeof(dateval));
|
||||
|
||||
dateval.tm_year = (s[2] - '0') * 1000 + (s[3] - '0') * 100 + (s[4] - '0') * 10 + s[5] - '0' - 1900;
|
||||
if (i > 6)
|
||||
dateval.tm_mon = (s[6] - '0') * 10 + s[7] - '0' - 1;
|
||||
if (i > 8)
|
||||
dateval.tm_mday = (s[8] - '0') * 10 + s[9] - '0';
|
||||
else
|
||||
dateval.tm_mday = 1;
|
||||
if (i > 10)
|
||||
dateval.tm_hour = (s[10] - '0') * 10 + s[11] - '0';
|
||||
if (i > 12)
|
||||
dateval.tm_min = (s[12] - '0') * 10 + s[13] - '0';
|
||||
if (i > 14)
|
||||
dateval.tm_sec = (s[14] - '0') * 10 + s[15] - '0';
|
||||
|
||||
if (i >= 16 && s[i])
|
||||
{
|
||||
// Get zone info...
|
||||
if (s[i] == 'Z')
|
||||
{
|
||||
// UTC...
|
||||
@ -742,14 +770,20 @@ get_date_time(const char *s) // I - PDF date/time value
|
||||
// Timezone offset from UTC...
|
||||
if (isdigit(s[i + 1] & 255) && isdigit(s[i + 2] & 255) && s[i + 3] == '\'' && isdigit(s[i + 4] & 255) && isdigit(s[i + 5] & 255))
|
||||
{
|
||||
offset = (s[i + 1] - '0') * 36000 + (s[i + 2] - '0') * 3600 + (s[i + 4] - '0') * 600 + (s[i + 5] - '0') * 60;
|
||||
if (s[i] == '-')
|
||||
offset = -offset;
|
||||
|
||||
i += 6;
|
||||
|
||||
// Accept trailing quote, per PDF spec...
|
||||
if (s[i] == '\'')
|
||||
i ++;
|
||||
}
|
||||
}
|
||||
else if (!s[i])
|
||||
else
|
||||
{
|
||||
// Missing zone info, invalid date string...
|
||||
// Random zone info, invalid date string...
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -760,26 +794,24 @@ get_date_time(const char *s) // I - PDF date/time value
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Date value...
|
||||
memset(&dateval, 0, sizeof(dateval));
|
||||
// Convert date value to time_t...
|
||||
#if _WIN32
|
||||
if ((t = _mkgmtime(&dateval)) < 0)
|
||||
return (0);
|
||||
#elif defined(HAVE_TIMEGM)
|
||||
if ((t = timegm(&dateval)) < 0)
|
||||
return (0);
|
||||
#else
|
||||
if ((t = mktime(&dateval)) < 0)
|
||||
return (0);
|
||||
|
||||
dateval.tm_year = (s[2] - '0') * 1000 + (s[3] - '0') * 100 + (s[4] - '0') * 10 + s[5] - '0' - 1900;
|
||||
dateval.tm_mon = (s[6] - '0') * 10 + s[7] - '0' - 1;
|
||||
dateval.tm_mday = (s[8] - '0') * 10 + s[9] - '0';
|
||||
dateval.tm_hour = (s[10] - '0') * 10 + s[11] - '0';
|
||||
dateval.tm_min = (s[12] - '0') * 10 + s[13] - '0';
|
||||
dateval.tm_sec = (s[14] - '0') * 10 + s[15] - '0';
|
||||
# if defined(HAVE_TM_GMTOFF)
|
||||
localtime_r(&t, &dateval);
|
||||
t -= dateval.tm_gmtoff;
|
||||
# else
|
||||
t -= timezone;
|
||||
# endif // HAVE_TM_GMTOFF
|
||||
#endif // _WIN32
|
||||
|
||||
if (s[16] == 'Z')
|
||||
{
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = (s[17] - '0') * 600 + (s[18] - '0') * 60 + (s[19] - '0') * 10 + s[20] - '0';
|
||||
if (s[16] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
return (mktime(&dateval) + offset);
|
||||
return (t + offset);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user