From 2e753fa3d7ebdc6ff142680461610c9db6cac947 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 3 Jan 2009 12:10:40 +0100 Subject: [PATCH 1/1] More issues with overlong returns. --- bytesource.c | 44 +++++++++++++++++++++++--------------------- bytesource_test.c | 11 ++++++++--- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/bytesource.c b/bytesource.c index fed7551..ca260a1 100644 --- a/bytesource.c +++ b/bytesource.c @@ -44,7 +44,7 @@ uint8_t byte_source_read_marker(struct byte_source* src) uint8_t ret = src->bytes[1]; memmove(src->bytes, src->bytes + 2, src->bytes_available - 2); src->bytes_available -= 2; - + return ret; } @@ -81,7 +81,7 @@ ssize_t byte_source_input_func(void* source, uint8_t* buf, size_t len) src->bytes_available += bytes_read; } - + // Now unstuff as much as we can. First of all, if there's a 0xFF at the // end of the buffer, we don't include it this time; the unstuff function // will only give us an error since it can't decide if it's a marker or @@ -94,45 +94,47 @@ ssize_t byte_source_input_func(void* source, uint8_t* buf, size_t len) end_marker = true; } - int unstuffed_bytes = (*unstuff_choice)(buf, src->bytes, bytes_to_unstuff); - assert(unstuffed_bytes != 0); - if (unstuffed_bytes > 0) { - // Fast path: No markers in the data. We can basically just - // return it. - if (end_marker) { - src->bytes_available = 1; - src->bytes[0] = 0xff; - } else { - src->bytes_available = 0; - src->bytes[0] = 0; + // Fast path: No markers in the data, we don't have more data than we + // need. We can basically just return it. + if (bytes_to_unstuff <= len) { + int unstuffed_bytes = (*unstuff_choice)(buf, src->bytes, bytes_to_unstuff); + assert(unstuffed_bytes != 0); + if (unstuffed_bytes > 0) { + // Fast path: No markers in the data. We can basically just + // return it. + if (end_marker) { + src->bytes_available = 1; + src->bytes[0] = 0xff; + } else { + src->bytes_available = 0; + } + return unstuffed_bytes; } - return unstuffed_bytes; } // Slow path: There was a marker in the data. Unstuff manually until // we hit the marker, then return that. - assert(unstuffed_bytes == -1); unsigned bytes_read; unsigned bytes_written = 0; - for (bytes_read = 0; bytes_read < src->bytes_available; ++bytes_read) { - buf[bytes_written++] = src->bytes[bytes_read]; + for (bytes_read = 0; bytes_read < bytes_to_unstuff && bytes_written < len; ++bytes_read) { if (src->bytes[bytes_read] != MARKER_CHAR) { + buf[bytes_written++] = src->bytes[bytes_read]; continue; } assert(bytes_read < src->bytes_available); if (src->bytes[bytes_read + 1] == STUFF_MARKER) { + src->bytes[bytes_written++] = MARKER_CHAR; + // Skip the stuff byte. ++bytes_read; - continue; } else { // OK, this is our marker. break; - } + } } memmove(src->bytes, src->bytes + bytes_read, src->bytes_available - bytes_read); src->bytes_available -= bytes_read; - assert(bytes_written >= 1); - return bytes_written - 1; + return bytes_written; } diff --git a/bytesource_test.c b/bytesource_test.c index 36c6da2..6c692cb 100644 --- a/bytesource_test.c +++ b/bytesource_test.c @@ -161,18 +161,23 @@ void test_small_reads() struct byte_source source; init_byte_source(&source, custom_read, &ud); + uint8_t buf[4096]; + ssize_t ret; + + ret = byte_source_input_func(&source, buf, 4096); + assert(ret == 0); + uint8_t marker = byte_source_read_marker(&source); assert(marker == 0x80); - uint8_t buf[4096]; for (unsigned i = 0; i < 8; ++i) { - ssize_t ret = byte_source_input_func(&source, buf, 1); + ret = byte_source_input_func(&source, buf, 1); assert(ret == 1); assert(buf[0] == i); } // Now EOF. - ssize_t ret = byte_source_input_func(&source, buf, 4096); + ret = byte_source_input_func(&source, buf, 4096); assert(ret == 0); } -- 2.39.2