Changeset: 00669e4ebaee for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=00669e4ebaee
Modified Files:
monetdb5/modules/mal/mal_io.c
Branch: default
Log Message:
Prevent potential for bus error by limiting scan to buffer.
strchr stop at a NUL byte or when it finds the character it's looking
for, but if the mmap'ed file ends exactly at a page boundary and
doesn't end in a newline, these strchr calls will happily continue
into un-mmap-ed terrain.
Also fixed an off-by-one: the memcpy plus subsequent assignment to
dst[l] never wrote to dst[l-1].
diffs (75 lines):
diff --git a/monetdb5/modules/mal/mal_io.c b/monetdb5/modules/mal/mal_io.c
--- a/monetdb5/modules/mal/mal_io.c
+++ b/monetdb5/modules/mal/mal_io.c
@@ -761,21 +761,24 @@ IOimport(int *ret, int *bid, str *fnme)
}
#endif
base = cur = (char *) MT_mmap(*fnme, MMAP_SEQUENTIAL, 0,
(size_t) st.st_size);
- end = cur + st.st_size;
if (cur == (char *) -1) {
BBPunfix(b->batCacheid);
throw(MAL, "io.mport", OPERATION_FAILED "MT_mmap()");
}
+ end = cur + st.st_size;
}
/* Parse a line. Copy it into a buffer. Concat broken lines with a
slash. */
while (cur < end) {
- str dst = buf, src = cur, p = strchr(cur, '\n');
- size_t l = p - cur;
+ str dst = buf, src = cur, p;
+ size_t l;
- if (!p) {
- p = end;
- } else
+ /* like p = strchr(cur, '\n') but with extra bounds check */
+ for (p = cur; p < end && *p != '\n'; p++)
+ ;
+ l = p - cur;
+
+ if (p < end) {
while (src[l - 1] == '\\') {
if (buf+bufsize < dst+l) {
size_t len = dst - buf;
@@ -786,20 +789,21 @@ IOimport(int *ret, int *bid, str *fnme)
memcpy(dst, src, l-1);
dst += l - 1;
src += l + 1;
- if ((p = strchr(src, '\n')) == 0) {
- p = end;
+ for (p = src; p < end && *p != '\n'; p++)
+ ;
+ if (p == end)
break;
- }
l = p - src;
}
-
+ }
+
if (buf+bufsize < dst+l) {
size_t len = dst - buf;
size_t inc = (size_t) ((dst+l) - buf);
buf = (char*) GDKrealloc((void*) buf, bufsize =
MAX(inc,bufsize)*2);
dst = buf + len;
}
- memcpy(dst, src, l-1);
+ memcpy(dst, src, l);
dst[l] = 0;
cur = p + 1;
/* Parse the line, and insert a BUN. */
@@ -808,8 +812,11 @@ IOimport(int *ret, int *bid, str *fnme)
if (*p == '#')
continue;
- for (;*p && *p != '['; p++);
- if (*p) for (p++; *p && GDKisspace(*p); p++);
+ for (;*p && *p != '['; p++)
+ ;
+ if (*p)
+ for (p++; *p && GDKisspace(*p); p++)
+ ;
if (*p == 0) {
char msg[BUFSIZ];
BBPunfix(*ret=b->batCacheid);
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list