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 Checkin-list@monetdb.org http://mail.monetdb.org/mailman/listinfo/checkin-list