summaryrefslogtreecommitdiff
path: root/src/locale
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-07-29 11:48:36 -0400
committerRich Felker <dalias@aerifal.cx>2014-07-29 11:48:36 -0400
commit6e89210669dfc93302a181a80ed440132e41f0dd (patch)
treea78d6870931eed250ebf489ac54abd438a993804 /src/locale
parent73d2a3bfda462eebe8291eb788ef8be567a9add8 (diff)
downloadmusl-6e89210669dfc93302a181a80ed440132e41f0dd.tar.gz
musl-6e89210669dfc93302a181a80ed440132e41f0dd.tar.bz2
musl-6e89210669dfc93302a181a80ed440132e41f0dd.tar.xz
musl-6e89210669dfc93302a181a80ed440132e41f0dd.zip
harden mo file processing for locale/translations
rather than just checking that the start of the string lies within the mapping, also check that the nominal length remains within the mapping, and that the null terminator is present at the nominal length. this ensures that the caller, using the result as a C string, will not read past the end of the mapping. the nominal length is never exposed to the caller, but it's useful internally to find where the null terminator should be without having to restort to linear search via strnlen/memchr.
Diffstat (limited to 'src/locale')
-rw-r--r--src/locale/__mo_lookup.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/locale/__mo_lookup.c b/src/locale/__mo_lookup.c
index 8112d91c..d18ab774 100644
--- a/src/locale/__mo_lookup.c
+++ b/src/locale/__mo_lookup.c
@@ -18,12 +18,16 @@ const char *__mo_lookup(const void *p, size_t size, const char *s)
o/=4;
t/=4;
for (;;) {
+ uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
- if (os >= size) return 0;
+ if (os >= size || ol >= size-os || ((char *)p)[os+ol])
+ return 0;
int sign = strcmp(s, (char *)p + os);
if (!sign) {
+ uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
- if (ts >= size) return 0;
+ if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
+ return 0;
return (char *)p + ts;
}
else if (n == 1) return 0;