1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
From f2903432bf8779f32237cc2e620e2fb0ca161ffa Mon Sep 17 00:00:00 2001
From: Derick Rethans <github@derickrethans.nl>
Date: Mon, 26 Apr 2021 09:59:01 +0100
Subject: [PATCH] Fixed issue #112: Support empty POSIX string in older TZif2
files
---
parse_tz.c | 19 ++++++++++++---
tests/c/files/Casablanca_AmazonLinux1 | Bin 0 -> 2428 bytes
tests/c/files/Nuuk_AmazonLinux1 | Bin 0 -> 8294 bytes
tests/c/parse_posix.cpp | 32 ++++++++++++++++++++++++++
timelib.c | 4 +++-
timelib.h | 8 ++++---
6 files changed, 56 insertions(+), 7 deletions(-)
create mode 100644 tests/c/files/Casablanca_AmazonLinux1
create mode 100644 tests/c/files/Nuuk_AmazonLinux1
diff --git a/ext/date/lib/parse_tz.c b/parse_tz.c
index ffeae2e..4e31b9e 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -553,11 +553,22 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
timelib_free(date_str);
}
+ if (!tz->posix_string) {
+ printf("\n%43sNo POSIX string\n", "");
+ return;
+ }
+
+ if (strcmp("", tz->posix_string) == 0) {
+ printf("\n%43sEmpty POSIX string\n", "");
+ return;
+ }
+
printf("\n%43sPOSIX string: %s\n", "", tz->posix_string);
- if (tz->posix_info->std) {
+ if (tz->posix_info && tz->posix_info->std) {
trans_str = format_offset_type(tz, tz->posix_info->type_index_std_type);
printf("%43sstd: %s\n", "", trans_str);
timelib_free(trans_str);
+
if (tz->posix_info->dst) {
trans_str = format_offset_type(tz, tz->posix_info->type_index_dst_type);
printf("%43sdst: %s\n", "", trans_str);
@@ -693,8 +704,10 @@ timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *t
}
read_posix_string(&tzf, tmp);
- if (!integrate_posix_string(tmp)) {
- *error_code = TIMELIB_ERROR_POSIX_MISSING_TTINFO;
+ if (strcmp("", tmp->posix_string) == 0) {
+ *error_code = TIMELIB_ERROR_EMPTY_POSIX_STRING;
+ } else if (!integrate_posix_string(tmp)) {
+ *error_code = TIMELIB_ERROR_CORRUPT_POSIX_STRING;
timelib_tzinfo_dtor(tmp);
return NULL;
}
diff --git a/ext/date/lib/timelib.c b/timelib.c
index 8db4df1..92366be 100644
--- a/ext/date/lib/timelib.c
+++ b/ext/date/lib/timelib.c
@@ -35,7 +35,7 @@
#define TIMELIB_LLABS(y) (y < 0 ? (y * -1) : y)
-const char *timelib_error_messages[9] = {
+const char *timelib_error_messages[10] = {
"No error",
"Can not allocate buffer for parsing",
"Corrupt tzfile: The transitions in the file don't always increase",
@@ -44,6 +44,8 @@ const char *timelib_error_messages[9] = {
"The version used in this timezone identifier is unsupported",
"No timezone with this name could be found",
"A 'slim' timezone file has been detected",
+ "The embedded POSIX string is not valid",
+ "The embedded POSIX string is empty"
};
const char *timelib_get_error_message(int error_code)
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h
index 7073c6c..8e82e58 100644
--- a/ext/date/lib/timelib.h
+++ b/ext/date/lib/timelib.h
@@ -375,7 +375,8 @@ typedef struct _timelib_tzdb {
#define TIMELIB_UNSET -99999
/* An entry for each of these error codes is also in the
- * timelib_error_messages array in timelib.c */
+ * timelib_error_messages array in timelib.c.
+ * Codes 0x00, 0x07, and 0x09 are warnings only. */
#define TIMELIB_ERROR_NO_ERROR 0x00
#define TIMELIB_ERROR_CANNOT_ALLOCATE 0x01
#define TIMELIB_ERROR_CORRUPT_TRANSITIONS_DONT_INCREASE 0x02
@@ -383,8 +384,9 @@ typedef struct _timelib_tzdb {
#define TIMELIB_ERROR_CORRUPT_NO_ABBREVIATION 0x04
#define TIMELIB_ERROR_UNSUPPORTED_VERSION 0x05
#define TIMELIB_ERROR_NO_SUCH_TIMEZONE 0x06
-#define TIMELIB_ERROR_SLIM_FILE 0x07
-#define TIMELIB_ERROR_POSIX_MISSING_TTINFO 0x08
+#define TIMELIB_ERROR_SLIM_FILE 0x07 /* Warns if the file is SLIM, but we can't read it */
+#define TIMELIB_ERROR_CORRUPT_POSIX_STRING 0x08
+#define TIMELIB_ERROR_EMPTY_POSIX_STRING 0x09 /* Warns if the POSIX string is empty, but still produces results */
#ifdef __cplusplus
extern "C" {
|