X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Ftime%2F__tz.c;h=92c43a570a914641cb8ae8e6cb6733cacc1b1dd9;hb=f616294914e7c289791d856dca636bbccad5fef7;hp=81676d3b6d800e60b98c74feb0f895ed1a2c0712;hpb=190bbb992344e350925bb9ebc37775ba8cc4c19f;p=musl diff --git a/src/time/__tz.c b/src/time/__tz.c index 81676d3b..92c43a57 100644 --- a/src/time/__tz.c +++ b/src/time/__tz.c @@ -121,14 +121,14 @@ int __munmap(void *, size_t); static void do_tzset() { char buf[NAME_MAX+25], *pathname=buf+24; - const char *try, *s; + const char *try, *s, *p; const unsigned char *map = 0; size_t i; static const char search[] = "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0"; s = getenv("TZ"); - if (!s || !*s) s = __gmt; + if (!s || !*s) s = "/etc/localtime"; if (old_tz && !strcmp(s, old_tz)) return; @@ -138,7 +138,7 @@ static void do_tzset() * free so as not to pull it into static programs. Growth * strategy makes it so free would have minimal benefit anyway. */ i = strlen(s); - if (i > PATH_MAX+1) s = "", i = 0; + if (i > PATH_MAX+1) s = __gmt, i = 3; if (i >= old_tz_size) { old_tz_size *= 2; if (i >= old_tz_size) old_tz_size = i+1; @@ -147,37 +147,40 @@ static void do_tzset() } if (old_tz) memcpy(old_tz, s, i+1); - if (*s == ':') s++; - /* Non-suid can use an absolute tzfile pathname or a relative * pathame beginning with "."; in secure mode, only the * standard path will be searched. */ - if (*s == '/' || *s == '.') { - if (!libc.secure) map = __map_file(s, &map_size); - } else { - for (i=0; s[i] && s[i]!=','; i++) { - if (s[i]=='/') { - size_t l = strlen(s); - if (l > NAME_MAX || strchr(s, '.')) - break; + if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) { + if (*s == ':') s++; + if (*s == '/' || *s == '.') { + if (!libc.secure || !strcmp(s, "/etc/localtime")) + map = __map_file(s, &map_size); + } else { + size_t l = strlen(s); + if (l <= NAME_MAX && !strchr(s, '.')) { memcpy(pathname, s, l+1); pathname[l] = 0; - for (try=search; !map && *try; try+=l) { + for (try=search; !map && *try; try+=l+1) { l = strlen(try); memcpy(pathname-l, try, l); map = __map_file(pathname-l, &map_size); } - break; } } + if (!map) s = __gmt; + } + if (map && (map_size < 44 || memcmp(map, "TZif", 4))) { + __munmap((void *)map, map_size); + map = 0; + s = __gmt; } zi = map; if (map) { int scale = 2; if (sizeof(time_t) > 4 && map[4]=='2') { - size_t skip = zi_dotprod(zi, VEC(1,1,8,5,6,1), 6); - trans = zi+skip+44+20; + size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6); + trans = zi+skip+44+44; scale++; } else { trans = zi+44;