From 547715463aac3b670fd4a71005932bbc92eb0b85 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Tue, 24 Jan 2012 19:09:07 +0100 Subject: [PATCH] Fix a segfault reported by Etienne Renault using dve2check. * src/misc/intvcmp2.cc (stream_compression_base::run): Fix a case where the "id" of the compression to use would be miscalculated, causing wrong values to be encoded. * src/tgbatest/intvcmp2.cc: Add this particular test case. --- ChangeLog | 9 +++++++++ src/misc/intvcmp2.cc | 26 ++++++++++++++------------ src/tgbatest/intvcmp2.cc | 3 +++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 486cb29e2..9c0a9a133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-01-24 Alexandre Duret-Lutz + + Fix a segfault reported by Etienne Renault using dve2check. + + * src/misc/intvcmp2.cc (stream_compression_base::run): Fix a case + where the "id" of the compression to use would be miscalculated, + causing wrong values to be encoded. + * src/tgbatest/intvcmp2.cc: Add this particular test case. + 2012-01-20 Alexandre Duret-Lutz * NEWS: Add missing dates. diff --git a/src/misc/intvcmp2.cc b/src/misc/intvcmp2.cc index 57c354cef..c67aa1c3c 100644 --- a/src/misc/intvcmp2.cc +++ b/src/misc/intvcmp2.cc @@ -37,13 +37,13 @@ namespace spot // This implements integer compression inspired from "Simple-9". // // The first bits of an integer tell how the rest of the integer is coded: - // 00: 30 1-bit values - // 01: 10 3-bit values - // 10: 6 5-bit values - // 1100: 4 7-bit values - // 1101: 3 9-bit values (1 bit lost) - // 1110: 2 14-bit values - // 1111: 1 28-bit value + // 00: 30 1-bit values id=0 + // 01: 10 3-bit values id=1 + // 10: 6 5-bit values id=2 + // 1100: 4 7-bit values id=3 + // 1101: 3 9-bit values (1 bit lost) id=4 + // 1110: 2 14-bit values id=5 + // 1111: 1 28-bit value id=6 template class stream_compression_base @@ -94,7 +94,7 @@ namespace spot { unsigned id = 0; // Current level in the above two tables. unsigned curmax_allowed = max_allowed[id]; - unsigned compressable = 0; // Number of integer ready to pack. + unsigned compressable = 0; // Number of integers ready to pack. do { unsigned int val = self().data_at(compressable); @@ -103,17 +103,19 @@ namespace spot { curmax_allowed = max_allowed[++id]; - if (compressable >= max_count[id]) + if (compressable > max_count[id]) goto fast_encode; } + if (compressable >= max_count[id]) + goto fast_encode; } - while (likely(compressable < max_count[id] - && compressable < size_)); + while (likely(compressable < size_)); - assert(compressable <= max_count[id]); + assert(compressable < max_count[id]); // Since we have less data than the current "id" allows, // try to use more bits so we can encode faster. + id = count_to_level[compressable - 1]; if (compressable == max_count[id]) diff --git a/src/tgbatest/intvcmp2.cc b/src/tgbatest/intvcmp2.cc index a0581c9bf..9ab908067 100644 --- a/src/tgbatest/intvcmp2.cc +++ b/src/tgbatest/intvcmp2.cc @@ -127,5 +127,8 @@ int main() 0, 0, 0, 0, 0, 0, 0, 0, 9 }; errors += check(comp10, sizeof(comp10) / sizeof(*comp10)); + int comp11[] = { 2, 254, 254, 0, 1, 4, 0, 0, 0, 1, 0, 1, 253, 0 }; + errors += check(comp11, sizeof(comp11) / sizeof(*comp11)); + return errors; }