summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/tzcode/localtime.c.patch
blob: 0587b5ea7626b605849911c2efa2071e50795d26 (plain)
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
--- localtime.c	2020-05-16 21:54:00.533111800 -0700
+++ localtime.c.patched	2020-05-22 00:03:30.826646000 -0700
@@ -413,7 +413,7 @@
 };
 
 /* TZDIR with a trailing '/' rather than a trailing '\0'.  */
-static char const tzdirslash[sizeof TZDIR] = TZDIR "/";
+static char const tzdirslash[sizeof TZDIR + 1] = TZDIR "/";
 
 /* Local storage needed for 'tzloadbody'.  */
 union local_storage {
@@ -473,7 +473,7 @@
 		   would pull in stdio (and would fail if the
 		   resulting string length exceeded INT_MAX!).  */
 		memcpy(lsp->fullname, tzdirslash, sizeof tzdirslash);
-		strcpy(lsp->fullname + sizeof tzdirslash, name);
+		strcpy(lsp->fullname + sizeof tzdirslash - 1, name);
 
 		/* Set doaccess if NAME contains a ".." file name
 		   component, as such a name could read a file outside
@@ -488,11 +488,11 @@
 		name = lsp->fullname;
 	}
 	if (doaccess && access(name, R_OK) != 0)
-		return errno;
+		goto trydefrules;
 
 	fid = open(name, OPEN_MODE);
 	if (fid < 0)
-		return errno;
+		goto trydefrules;
 	nread = read(fid, up->buf, sizeof up->buf);
 	if (nread < (ssize_t)tzheadsize) {
 		int err = nread < 0 ? errno : EINVAL;
@@ -501,6 +501,17 @@
 	}
 	if (close(fid) < 0)
 		return errno;
+	if (0) {
+		const char *base;
+trydefrules:
+
+		base = strrchr(name, '/');
+		base = base ? base + 1 : name;
+		if (strcmp(base, TZDEFRULES))
+		    return errno;
+		nread = sizeof _posixrules_data;
+		memcpy(up->buf, _posixrules_data, nread);
+	}
 	for (stored = 4; stored <= 8; stored *= 2) {
 		int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
 		int_fast32_t ttisutcnt = detzcode(up->tzhead.tzh_ttisutcnt);
@@ -1417,6 +1428,8 @@
 tzsetlcl(char const *name)
 {
 	struct state *sp = __lclptr;
+	if (! name)
+		name = tzgetwintzi(__UNCONST(wildabbr), (char *) alloca (512));
 	int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
 	if (lcl < 0 ? lcl_is_set < 0
 	    : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)