diff options
author | openvcdiff@gmail.com <openvcdiff@gmail.com@132ac840-3546-0410-a738-d3f8764196be> | 2009-10-09 22:40:32 +0000 |
---|---|---|
committer | openvcdiff@gmail.com <openvcdiff@gmail.com@132ac840-3546-0410-a738-d3f8764196be> | 2009-10-09 22:40:32 +0000 |
commit | f1dd933c4e47a65889b4bba2a5f58b12aac53383 (patch) | |
tree | 2d1befb34b7fa64170a301e1d84e0bf4677f6afd | |
parent | baf44ead8ad43d5c600b7f89420905a7397489fb (diff) | |
download | open-vcdiff-f1dd933c4e47a65889b4bba2a5f58b12aac53383.tar.gz |
Fri, 09 Oct 2009 10:32:10 -0700 Google Inc. <opensource@google.com>
Release version 0.7 with the following changes:
* Fix a case in which VarintBE::Parse would read off the end of available
input if the variable-length integer began with leading zero bytes
with their continuation bits set (0x80 bytes.)
* Define std::string as string only within namespaces and class definitions
in case there is a string class defined at the outermost scope. If that
is the case, the HAS_GLOBAL_STRING label should be defined manually.
* Update with changes to gflags package as of 2009/07/23.
git-svn-id: http://open-vcdiff.googlecode.com/svn/trunk@27 132ac840-3546-0410-a738-d3f8764196be
-rw-r--r-- | ChangeLog | 11 | ||||
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | packages/deb/changelog | 6 | ||||
-rw-r--r-- | src/addrcache_test.cc | 2 | ||||
-rw-r--r-- | src/codetablewriter_interface.h | 6 | ||||
-rw-r--r-- | src/encodetable.h | 2 | ||||
-rw-r--r-- | src/encodetable_test.cc | 2 | ||||
-rw-r--r-- | src/gflags.cc | 22 | ||||
-rw-r--r-- | src/gflags/gflags.h | 13 | ||||
-rw-r--r-- | src/gflags_reporting.cc | 50 | ||||
-rw-r--r-- | src/google/vcdecoder.h | 2 | ||||
-rw-r--r-- | src/headerparser_test.cc | 2 | ||||
-rw-r--r-- | src/output_string_test.cc | 2 | ||||
-rw-r--r-- | src/varint_bigendian.cc | 84 | ||||
-rw-r--r-- | src/varint_bigendian.h | 17 | ||||
-rw-r--r-- | src/varint_bigendian_test.cc | 54 | ||||
-rw-r--r-- | src/vcdecoder.cc | 10 | ||||
-rw-r--r-- | src/vcdecoder2_test.cc | 14 | ||||
-rw-r--r-- | src/vcdecoder3_test.cc | 8 | ||||
-rw-r--r-- | src/vcdecoder_test.h | 2 | ||||
-rw-r--r-- | src/vcdiff_main.cc | 4 | ||||
-rw-r--r-- | src/vcdiffengine_test.cc | 2 | ||||
-rw-r--r-- | src/vcencoder_test.cc | 3 | ||||
-rw-r--r-- | vsprojects/config.h | 6 |
25 files changed, 166 insertions, 180 deletions
@@ -1,3 +1,14 @@ +Fri, 09 Oct 2009 10:32:10 -0700 Google Inc. <opensource@google.com> + + Release version 0.7 with the following changes: + * Fix a case in which VarintBE::Parse would read off the end of available + input if the variable-length integer began with leading zero bytes + with their continuation bits set (0x80 bytes.) + * Define std::string as string only within namespaces and class definitions + in case there is a string class defined at the outermost scope. If that + is the case, the HAS_GLOBAL_STRING label should be defined manually. + * Update with changes to gflags package as of 2009/07/23. + Thu, 09 Apr 2009 09:16:58 -0700 Google Inc. <opensource@google.com> Release version 0.6 with the following changes: @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for open-vcdiff 0.6. +# Generated by GNU Autoconf 2.61 for open-vcdiff 0.7. # # Report bugs to <opensource@google.com>. # @@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='open-vcdiff' PACKAGE_TARNAME='open-vcdiff' -PACKAGE_VERSION='0.6' -PACKAGE_STRING='open-vcdiff 0.6' +PACKAGE_VERSION='0.7' +PACKAGE_STRING='open-vcdiff 0.7' PACKAGE_BUGREPORT='opensource@google.com' ac_unique_file="README" @@ -1397,7 +1397,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures open-vcdiff 0.6 to adapt to many kinds of systems. +\`configure' configures open-vcdiff 0.7 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1467,7 +1467,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of open-vcdiff 0.6:";; + short | recursive ) echo "Configuration of open-vcdiff 0.7:";; esac cat <<\_ACEOF @@ -1569,7 +1569,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -open-vcdiff configure 0.6 +open-vcdiff configure 0.7 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1583,7 +1583,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by open-vcdiff $as_me 0.6, which was +It was created by open-vcdiff $as_me 0.7, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2274,7 +2274,7 @@ fi # Define the identity of the package. PACKAGE='open-vcdiff' - VERSION='0.6' + VERSION='0.7' cat >>confdefs.h <<_ACEOF @@ -22342,7 +22342,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by open-vcdiff $as_me 0.6, which was +This file was extended by open-vcdiff $as_me 0.7, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -22395,7 +22395,7 @@ Report bugs to <bug-autoconf@gnu.org>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -open-vcdiff config.status 0.6 +open-vcdiff config.status 0.7 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/configure.ac b/configure.ac index b47421c..feaa972 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,7 @@ # make sure we're interpreted by some minimal autoconf AC_PREREQ(2.57) -AC_INIT(open-vcdiff, 0.6, opensource@google.com) +AC_INIT(open-vcdiff, 0.7, opensource@google.com) AC_CONFIG_SRCDIR(README) AM_INIT_AUTOMAKE AM_CONFIG_HEADER(src/config.h) diff --git a/packages/deb/changelog b/packages/deb/changelog index cd17567..722e17f 100644 --- a/packages/deb/changelog +++ b/packages/deb/changelog @@ -1,3 +1,9 @@ +open-vcdiff (0.7-1) unstable; urgency=medium + + * New upstream release. + + -- Google Inc. <opensource@google.com> Fri, 09 Oct 2009 10:32:10 -0700 + open-vcdiff (0.6-1) unstable; urgency=low * New upstream release. diff --git a/src/addrcache_test.cc b/src/addrcache_test.cc index f93aaa7..64b7169 100644 --- a/src/addrcache_test.cc +++ b/src/addrcache_test.cc @@ -34,9 +34,7 @@ namespace { // class VCDiffAddressCacheTest : public testing::Test { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING VCDiffAddressCacheTest() : decode_position_(NULL), decode_position_end_(NULL), diff --git a/src/codetablewriter_interface.h b/src/codetablewriter_interface.h index 3c6ab29..7f2875a 100644 --- a/src/codetablewriter_interface.h +++ b/src/codetablewriter_interface.h @@ -7,8 +7,8 @@ // series of Add, Copy, and Run instructions and produces an output file in the // desired format. -#ifndef FASTNET_DELTAFORCE_VCDIFF_RFC3284_CODETABLEWRITER_INTERFACE_H_ -#define FASTNET_DELTAFORCE_VCDIFF_RFC3284_CODETABLEWRITER_INTERFACE_H_ +#ifndef OPEN_VCDIFF_CODETABLEWRITER_INTERFACE_H_ +#define OPEN_VCDIFF_CODETABLEWRITER_INTERFACE_H_ #include <stddef.h> // size_t @@ -50,4 +50,4 @@ class CodeTableWriterInterface { } // namespace open_vcdiff -#endif // FASTNET_DELTAFORCE_VCDIFF_RFC3284_CODETABLEWRITER_INTERFACE_H_ +#endif // OPEN_VCDIFF_CODETABLEWRITER_INTERFACE_H_ diff --git a/src/encodetable.h b/src/encodetable.h index 4566a86..016c6c7 100644 --- a/src/encodetable.h +++ b/src/encodetable.h @@ -107,9 +107,7 @@ class VCDiffCodeTableWriter : public CodeTableWriterInterface { const std::vector<int>& match_counts() const { return match_counts_; } private: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING // This is an estimate of the longest match size the encoder expects to find. // It is used to determine the initial size of the vector match_counts_. diff --git a/src/encodetable_test.cc b/src/encodetable_test.cc index e8e7dd7..cf41849 100644 --- a/src/encodetable_test.cc +++ b/src/encodetable_test.cc @@ -33,9 +33,7 @@ namespace { class CodeTableWriterTest : public testing::Test { protected: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING CodeTableWriterTest() : standard_writer(false), diff --git a/src/gflags.cc b/src/gflags.cc index def2dc1..2607997 100644 --- a/src/gflags.cc +++ b/src/gflags.cc @@ -143,7 +143,6 @@ # define PRIu64 "llu" #endif -using std::string; using std::map; using std::vector; using std::pair; @@ -168,6 +167,8 @@ DEFINE_string(undefok, "", namespace google { +using std::string; + // The help message indicating that the commandline flag has been // 'stripped'. It will not show up when doing "-help" and its // variants. The flag is stripped if STRIP_FLAG_HELP is set to 1 @@ -1036,6 +1037,25 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv, break; // we treat this as an unrecoverable error } else { value = (*argv)[++i]; // read next arg for value + + // Heuristic to detect the case where someone treats a string arg + // like a bool: + // --my_string_var --foo=bar + // We look for a flag of string type, whose value begins with a + // dash, and where the flag-name and value are separated by a + // space rather than an '='. + // To avoid false positives, we also require the word "true" + // or "false" in the help string. Without this, a valid usage + // "-lat -30.5" would trigger the warning. The common cases we + // want to solve talk about true and false as values. + if (value[0] == '-' + && strcmp(flag->type_name(), "string") == 0 + && (strstr(flag->help(), "true") + || strstr(flag->help(), "false"))) { + fprintf(stderr, "Did you really mean to set flag '%s'" + " to the value '%s'?\n", + flag->name(), value); + } } } diff --git a/src/gflags/gflags.h b/src/gflags/gflags.h index 2c2301a..5517ec4 100644 --- a/src/gflags/gflags.h +++ b/src/gflags/gflags.h @@ -415,7 +415,7 @@ class FlagRegisterer { void* current_storage, void* defvalue_storage); }; -#ifndef SWIG // In swig, ignore the main flag declarations +extern bool FlagsTypeWarn(const char *name); // If your application #defines STRIP_FLAG_HELP to a non-zero value // before #including this file, we remove the help message from the @@ -424,6 +424,10 @@ class FlagRegisterer { extern const char kStrippedFlagHelp[]; +} // namespace google + +#ifndef SWIG // In swig, ignore the main flag declarations + #if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 // Need this construct to avoid the 'defined but not used' warning. #define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp) @@ -468,13 +472,12 @@ namespace fLB { template<typename From> double IsBoolFlag(const From& from); bool IsBoolFlag(bool from); } -extern bool FlagsTypeWarn(const char *name); #define DECLARE_bool(name) DECLARE_VARIABLE(bool,B, name) // We have extra code here to make sure 'val' is actually a boolean. #define DEFINE_bool(name,val,txt) namespace fLB { \ const bool FLAGS_nonono##name = \ - (sizeof(::google::fLB::IsBoolFlag(val)) \ + (sizeof(::fLB::IsBoolFlag(val)) \ == sizeof(double)) \ ? ::google::FlagsTypeWarn(#name) : true; \ } \ @@ -510,7 +513,7 @@ extern bool FlagsTypeWarn(const char *name); #define DEFINE_string(name, val, txt) \ namespace fLS { \ static union { void* align; char s[sizeof(std::string)]; } s_##name[2]; \ - const string* const FLAGS_no##name = new (s_##name[0].s) std::string(val); \ + const std::string* const FLAGS_no##name = new (s_##name[0].s) std::string(val); \ static ::google::FlagRegisterer o_##name( \ #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ s_##name[0].s, new (s_##name[1].s) std::string(*FLAGS_no##name)); \ @@ -522,6 +525,4 @@ extern bool FlagsTypeWarn(const char *name); #endif // SWIG -} // namespace google - #endif // GOOGLE_GFLAGS_H_ diff --git a/src/gflags_reporting.cc b/src/gflags_reporting.cc index 8bca766..e3088ac 100644 --- a/src/gflags_reporting.cc +++ b/src/gflags_reporting.cc @@ -61,7 +61,6 @@ #define PATH_SEPARATOR '/' #endif -using std::string; using std::vector; // The 'reporting' flags. They all call exit(). @@ -84,6 +83,8 @@ DEFINE_bool(version, false, namespace google { +using std::string; + // -------------------------------------------------------------------- // DescribeOneFlag() // DescribeOneFlagInXML() @@ -191,18 +192,29 @@ static string XMLText(const string& txt) { return ans; } +static void AddXMLTag(string* r, const char* tag, const string& txt) { + *r += ('<'); + *r += (tag); + *r += ('>'); + *r += (XMLText(txt)); + *r += ("</"); + *r += (tag); + *r += ('>'); +} + static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) { // The file and flagname could have been attributes, but default // and meaning need to avoid attribute normalization. This way it // can be parsed by simple programs, in addition to xml parsers. - return (string("<flag>") + - "<file>" + XMLText(flag.filename) + "</file>" + - "<name>" + XMLText(flag.name) + "</name>" + - "<meaning>" + XMLText(flag.description) + "</meaning>" + - "<default>" + XMLText(flag.default_value) + "</default>" + - "<current>" + XMLText(flag.current_value) + "</current>" + - "<type>" + XMLText(flag.type) + "</type>" + - string("</flag>")); + string r("<flag>"); + AddXMLTag(&r, "file", flag.filename); + AddXMLTag(&r, "name", flag.name); + AddXMLTag(&r, "meaning", flag.description); + AddXMLTag(&r, "default", flag.default_value); + AddXMLTag(&r, "current", flag.current_value); + AddXMLTag(&r, "type", flag.type); + r += "</flag>"; + return r; } // -------------------------------------------------------------------- @@ -341,6 +353,15 @@ static void ShowVersion() { # endif } +static void AppendPrognameStrings(vector<string>* substrings, + const char* progname) { + string r("/"); + r += progname; + substrings->push_back(r + "."); + substrings->push_back(r + "-main."); + substrings->push_back(r + "_main."); +} + // -------------------------------------------------------------------- // HandleCommandLineHelpFlags() // Checks all the 'reporting' commandline flags to see if any @@ -353,13 +374,12 @@ void HandleCommandLineHelpFlags() { const char* progname = ProgramInvocationShortName(); extern void (*commandlineflags_exitfunc)(int); // in gflags.cc + vector<string> substrings; + AppendPrognameStrings(&substrings, progname); + if (FLAGS_helpshort) { // show only flags related to this binary: // E.g. for fileutil.cc, want flags containing ... "/fileutil." cc - vector<string> substrings; - substrings.push_back(string("/") + progname + "."); - substrings.push_back(string("/") + progname + "-main."); - substrings.push_back(string("/") + progname + "_main."); ShowUsageWithFlagsMatching(progname, substrings); commandlineflags_exitfunc(1); // almost certainly exit() @@ -385,10 +405,6 @@ void HandleCommandLineHelpFlags() { // filename like "/progname.cc", and take the dirname of that. vector<CommandLineFlagInfo> flags; GetAllFlags(&flags); - vector<string> substrings; - substrings.push_back(string("/") + progname + "."); - substrings.push_back(string("/") + progname + "-main."); - substrings.push_back(string("/") + progname + "_main."); string last_package; for (vector<CommandLineFlagInfo>::const_iterator flag = flags.begin(); flag != flags.end(); diff --git a/src/google/vcdecoder.h b/src/google/vcdecoder.h index c834517..3b3b9ec 100644 --- a/src/google/vcdecoder.h +++ b/src/google/vcdecoder.h @@ -140,9 +140,7 @@ class VCDiffStreamingDecoder { // class VCDiffDecoder { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING VCDiffDecoder() { } ~VCDiffDecoder() { } diff --git a/src/headerparser_test.cc b/src/headerparser_test.cc index 3a7cfa4..66ed824 100644 --- a/src/headerparser_test.cc +++ b/src/headerparser_test.cc @@ -28,9 +28,7 @@ using std::vector; class VCDiffHeaderParserTest : public testing::Test { protected: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING static const int kTestSize = 1024; diff --git a/src/output_string_test.cc b/src/output_string_test.cc index 2b655e9..3f534dc 100644 --- a/src/output_string_test.cc +++ b/src/output_string_test.cc @@ -28,9 +28,7 @@ namespace { class OutputStringTest : public testing::Test { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING OutputStringTest() : string_("ab"), output_string_(&string_) { } diff --git a/src/varint_bigendian.cc b/src/varint_bigendian.cc index 5098ed2..9166012 100644 --- a/src/varint_bigendian.cc +++ b/src/varint_bigendian.cc @@ -26,93 +26,35 @@ namespace open_vcdiff { template<> const int32_t VarintBE<int32_t>::kMaxVal = 0x7FFFFFFF; template<> const int64_t VarintBE<int64_t>::kMaxVal = 0x7FFFFFFFFFFFFFFFULL; -// Check whether the variable-length integer runs off the end -// of the available input. If there are few bytes left in the input, -// then AND together their most significant bits (the continuation bits) -// and see if they are all set; if so, the integer runs off the end of the -// available input. Only kMaxBytes - 1 bytes need be checked; if there are -// kMaxBytes bytes with their continuation bits set, it is an error condition -// and it will be caught later. -// -// The function is specific to a particular integer type (number of bits.) -// -template <> -inline bool VarintBE<int32_t>::ReachedEndOfData(const char* parse_ptr, - const char* limit) { - unsigned char reached_end_of_data_flag = 0x80; - const unsigned char* const bitwise_ptr = - reinterpret_cast<const unsigned char*>(parse_ptr); - switch (limit - parse_ptr) { - case 4: reached_end_of_data_flag &= bitwise_ptr[3]; - // fall through - case 3: reached_end_of_data_flag &= bitwise_ptr[2]; - // fall through - case 2: reached_end_of_data_flag &= bitwise_ptr[1]; - // fall through - case 1: reached_end_of_data_flag &= bitwise_ptr[0]; - return (reached_end_of_data_flag == 0x80); - case 0: return true; - } - return false; -} - -template <> -inline bool VarintBE<int64_t>::ReachedEndOfData(const char* parse_ptr, - const char* limit) { - unsigned char reached_end_of_data_flag = 0x80; - const unsigned char* const bitwise_ptr = - reinterpret_cast<const unsigned char*>(parse_ptr); - switch (limit - parse_ptr) { - case 8: reached_end_of_data_flag &= bitwise_ptr[7]; - // fall through - case 7: reached_end_of_data_flag &= bitwise_ptr[6]; - // fall through - case 6: reached_end_of_data_flag &= bitwise_ptr[5]; - // fall through - case 5: reached_end_of_data_flag &= bitwise_ptr[4]; - // fall through - case 4: reached_end_of_data_flag &= bitwise_ptr[3]; - // fall through - case 3: reached_end_of_data_flag &= bitwise_ptr[2]; - // fall through - case 2: reached_end_of_data_flag &= bitwise_ptr[1]; - // fall through - case 1: reached_end_of_data_flag &= bitwise_ptr[0]; - return (reached_end_of_data_flag == 0x80); - case 0: return true; - } - return false; -} - // Reads a variable-length integer from **varint_ptr // and returns it in a fixed-length representation. Increments -// *varint_ptr by the number of bytes read. Will only read -// a maximum of kMaxBytes bytes from **varint_ptr even if the input data -// has the continuation bit set for more bytes. Will not read +// *varint_ptr by the number of bytes read. Will not read // past limit. Returns RESULT_ERROR if the value parsed -// does not fit in a non-negative signed integer. +// does not fit in a non-negative signed integer, or if limit is NULL. // Returns RESULT_END_OF_DATA if address_stream_end is reached // before the whole integer can be decoded. // template <typename SignedIntegerType> SignedIntegerType VarintBE<SignedIntegerType>::Parse(const char* limit, const char** varint_ptr) { - const char* parse_ptr = *varint_ptr; - if (ReachedEndOfData(parse_ptr, limit)) { - return RESULT_END_OF_DATA; + if (!limit) { + return RESULT_ERROR; } - SignedIntegerType result = *parse_ptr & 0x7F; - while (*parse_ptr & 0x80) { + SignedIntegerType result = 0; + for (const char* parse_ptr = *varint_ptr; parse_ptr < limit; ++parse_ptr) { + result += *parse_ptr & 0x7F; + if (!(*parse_ptr & 0x80)) { + *varint_ptr = parse_ptr + 1; + return result; + } if (result > (kMaxVal >> 7)) { // Shifting result by 7 bits would produce a number too large // to be stored in a non-negative SignedIntegerType (an overflow.) return RESULT_ERROR; } - ++parse_ptr; - result = (result << 7) + (*parse_ptr & 0x7F); + result = result << 7; } - *varint_ptr = parse_ptr + 1; - return result; + return RESULT_END_OF_DATA; } template <typename SignedIntegerType> diff --git a/src/varint_bigendian.h b/src/varint_bigendian.h index d5b63d5..1b88432 100644 --- a/src/varint_bigendian.h +++ b/src/varint_bigendian.h @@ -74,9 +74,7 @@ template<> class VarintMaxBytes<int64_t> { template <typename SignedIntegerType> class VarintBE { // BE stands for Big-Endian public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING // The maximum positive value represented by a SignedIntegerType. static const SignedIntegerType kMaxVal; @@ -87,15 +85,14 @@ class VarintBE { // BE stands for Big-Endian // Attempts to parse a big-endian varint from a prefix of the bytes // in [ptr,limit-1] and convert it into a signed, non-negative 32-bit - // integer. Never reads a character at or beyond limit, and never reads - // a character at or beyond (*ptr + kMaxBytes). + // integer. Never reads a character at or beyond limit. // If a parsed varint would exceed the maximum value of // a <SignedIntegerType>, returns RESULT_ERROR and does not modify *ptr. // If parsing a varint at *ptr (without exceeding the capacity of // a <SignedIntegerType>) would require reading past limit, // returns RESULT_END_OF_DATA and does not modify *ptr. - // If limit == NULL, or limit < *ptr, no error will be signalled, but it is - // recommended that a limit always be supplied for security reasons. + // If limit == NULL, returns RESULT_ERROR. + // If limit < *ptr, returns RESULT_END_OF_DATA. static SignedIntegerType Parse(const char* limit, const char** ptr); // Returns the encoding length of the specified value. @@ -123,14 +120,6 @@ class VarintBE { // BE stands for Big-Endian // The value of v must not be negative. static int EncodeInternal(SignedIntegerType v, char* varint_buf); - // Returns true if bytes_left <= kMaxBytes AND the next bytes_left bytes - // starting at parse_ptr all have their continuation bit (most significant - // bit) set. This means that there may or may not be a valid encoded - // varint at parse_ptr, but it cannot be read or validated until more - // input is available. - static inline bool ReachedEndOfData(const char* parse_ptr, - const char* limit); - // These are private to avoid constructing any objects of this type VarintBE(); VarintBE(const VarintBE&); // NOLINT diff --git a/src/varint_bigendian_test.cc b/src/varint_bigendian_test.cc index 11b50a1..3debf51 100644 --- a/src/varint_bigendian_test.cc +++ b/src/varint_bigendian_test.cc @@ -26,9 +26,7 @@ namespace { class VarintBETestCommon : public testing::Test { protected: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING VarintBETestCommon() : varint_buf_(VarintBE<int64_t>::kMaxBytes), @@ -90,13 +88,13 @@ class VarintBETestTemplate : public VarintBETestCommon { void TemplateTestParseNullPointer(); void TemplateTestEndPointerPrecedesBeginning(); void TemplateTestParseVarintTooLong(); - void TemplateTestParseIncompleteVarint(); void TemplateTestParseZero(); void TemplateTestParseCADA1(); void TemplateTestParseEmpty(); void TemplateTestParse123456789(); void TemplateTestDecode31Bits(); void TemplateTestEncodeDecodeRandom(); + void TemplateTestContinuationBytesPastEndOfInput(); }; typedef VarintBETestTemplate<int32_t> VarintBEInt32Test; @@ -221,10 +219,26 @@ TEMPLATE_TEST_F(Test, ParseVarintTooLong) { &parse_data_ptr_)); } -TEMPLATE_TEST_F(Test, ParseIncompleteVarint) { - EXPECT_EQ(RESULT_END_OF_DATA, - VarintType::Parse(parse_data_ptr_ + VarintType::kMaxBytes - 1, - &parse_data_ptr_)); +TEST_F(VarintBEInt32Test, ParseFourFFs) { + // For a 31-bit non-negative VarintBE, the sequence FF FF FF FF is invalid. + // Even though the largest allowable 31-bit value occupies 5 bytes as a + // Varint, it shouldn't have the highest bits set and so can't begin with FF. + EXPECT_EQ(RESULT_ERROR, VarintType::Parse(parse_data_ptr_ + 4, + &parse_data_ptr_)); +} + +TEST_F(VarintBEInt32Test, ParseThreeFFs) { + EXPECT_EQ(RESULT_END_OF_DATA, VarintType::Parse(parse_data_ptr_ + 3, + &parse_data_ptr_)); +} + +TEST_F(VarintBEInt64Test, ParseEightFFs) { + // For a 63-bit non-negative VarintBE, a series of eight FFs is valid, because + // the largest allowable 63-bit value is expressed as eight FF bytes followed + // by a 7F byte. This is in contrast to the 32-bit case (see ParseFourFFs, + // above.) + EXPECT_EQ(RESULT_END_OF_DATA, VarintType::Parse(parse_data_ptr_ + 8, + &parse_data_ptr_)); } TEMPLATE_TEST_F(Test, ParseZero) { @@ -242,18 +256,17 @@ TEMPLATE_TEST_F(Test, ParseCADA1) { EXPECT_EQ(parse_data_CADA1 + 3, parse_data_ptr_); } -#ifdef GTEST_HAS_DEATH_TEST -TEMPLATE_TEST_F(DeathTest, ParseNullPointer) { - // limit == NULL is not an error +TEMPLATE_TEST_F(Test, ParseNullPointer) { parse_data_ptr_ = parse_data_CADA1; - EXPECT_EQ(0x12AD01, VarintType::Parse((const char*) NULL, &parse_data_ptr_)); + EXPECT_EQ(RESULT_ERROR, + VarintType::Parse((const char*) NULL, &parse_data_ptr_)); } -#endif // GTEST_HAS_DEATH_TEST TEMPLATE_TEST_F(Test, EndPointerPrecedesBeginning) { // This is not an error. parse_data_ptr_ = parse_data_CADA1; - EXPECT_EQ(0x12AD01, VarintType::Parse(parse_data_ptr_ - 1, &parse_data_ptr_)); + EXPECT_EQ(RESULT_END_OF_DATA, + VarintType::Parse(parse_data_ptr_ - 1, &parse_data_ptr_)); } TEMPLATE_TEST_F(Test, ParseEmpty) { @@ -320,5 +333,20 @@ TEMPLATE_TEST_F(Test, EncodeDecodeRandom) { } } +// If only 10 bytes of data are available, but there are 20 continuation +// bytes, Parse() should not read to the end of the continuation bytes. It is +// legal (according to the RFC3284 spec) to use any number of continuation +// bytes, but they should not cause us to read past the end of available input. +TEMPLATE_TEST_F(Test, ContinuationBytesPastEndOfInput) { + const char parse_data_20_continuations[] = + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x00 }; + parse_data_ptr_ = parse_data_20_continuations; + EXPECT_EQ(RESULT_END_OF_DATA, + VarintType::Parse(parse_data_20_continuations + 10, + &parse_data_ptr_)); +} + } // anonymous namespace } // namespace open_vcdiff diff --git a/src/vcdecoder.cc b/src/vcdecoder.cc index 5454e24..49d3940 100644 --- a/src/vcdecoder.cc +++ b/src/vcdecoder.cc @@ -89,10 +89,6 @@ namespace open_vcdiff { // class VCDiffDeltaFileWindow { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING - typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING - VCDiffDeltaFileWindow(); ~VCDiffDeltaFileWindow(); @@ -319,9 +315,7 @@ inline void VCDiffDeltaFileWindow::Init(VCDiffStreamingDecoderImpl* parent) { class VCDiffStreamingDecoderImpl { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING // The default maximum target file size (and target window size) if // SetMaximumTargetFileSize() is not called. @@ -830,9 +824,7 @@ namespace { class TrackNewOutputText { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING explicit TrackNewOutputText(const string& decoded_target) : decoded_target_(decoded_target), @@ -1051,7 +1043,7 @@ VCDiffResult VCDiffDeltaFileWindow::SetUpWindowSections( // VCDiffResult VCDiffDeltaFileWindow::ReadHeader( ParseableChunk* parseable_chunk) { - string* decoded_target = parent_->decoded_target(); + std::string* decoded_target = parent_->decoded_target(); VCDiffHeaderParser header_parser(parseable_chunk->UnparsedData(), parseable_chunk->End()); size_t source_segment_position = 0; diff --git a/src/vcdecoder2_test.cc b/src/vcdecoder2_test.cc index 74dc3f8..d498504 100644 --- a/src/vcdecoder2_test.cc +++ b/src/vcdecoder2_test.cc @@ -268,7 +268,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the source segment size - EXPECT_EQ(delta_file_header_.size() + 5, i); + EXPECT_EQ(delta_file_header_.size() + 4, i); break; } } @@ -333,7 +333,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, SourceSegmentPosNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the source segment pos - EXPECT_EQ(delta_file_header_.size() + 7, i); + EXPECT_EQ(delta_file_header_.size() + 6, i); break; } } @@ -430,7 +430,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, DeltaEncodingLengthNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the delta encoding length - EXPECT_EQ(delta_file_header_.size() + 8, i); + EXPECT_EQ(delta_file_header_.size() + 7, i); break; } } @@ -523,7 +523,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, TargetWindowSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the target window size - EXPECT_EQ(delta_file_header_.size() + 9, i); + EXPECT_EQ(delta_file_header_.size() + 8, i); break; } } @@ -680,7 +680,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, AddRunDataSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the add/run data segment size - EXPECT_EQ(delta_file_header_.size() + 12, i); + EXPECT_EQ(delta_file_header_.size() + 11, i); break; } } @@ -777,7 +777,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, InstructionsSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the instructions segment size - EXPECT_EQ(delta_file_header_.size() + 13, i); + EXPECT_EQ(delta_file_header_.size() + 12, i); break; } } @@ -873,7 +873,7 @@ TEST_F(VCDiffStandardDecoderTestByteByByte, CopyAddressSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail after decoding the copy address segment size - EXPECT_EQ(delta_file_header_.size() + 14, i); + EXPECT_EQ(delta_file_header_.size() + 13, i); break; } } diff --git a/src/vcdecoder3_test.cc b/src/vcdecoder3_test.cc index 62b47be..f3f8b5c 100644 --- a/src/vcdecoder3_test.cc +++ b/src/vcdecoder3_test.cc @@ -896,7 +896,7 @@ TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopySizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail at the position that was altered - EXPECT_EQ(delta_file_header_.size() + 0x10, i); + EXPECT_EQ(delta_file_header_.size() + 0x0F, i); break; } } @@ -967,7 +967,7 @@ TEST_F(VCDiffInterleavedDecoderTestByteByByte, CopyAddressNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail at the position that was altered - EXPECT_EQ(delta_file_header_.size() + 0x11, i); + EXPECT_EQ(delta_file_header_.size() + 0x10, i); break; } } @@ -1088,7 +1088,7 @@ TEST_F(VCDiffInterleavedDecoderTestByteByByte, AddSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail at the position that was altered - EXPECT_EQ(delta_file_header_.size() + 0x13, i); + EXPECT_EQ(delta_file_header_.size() + 0x12, i); break; } } @@ -1209,7 +1209,7 @@ TEST_F(VCDiffInterleavedDecoderTestByteByByte, RunSizeNegative) { if (!decoder_.DecodeChunk(&delta_file_[i], 1, &output_)) { failed = true; // It should fail at the position that was altered - EXPECT_EQ(delta_file_header_.size() + 0x63, i); + EXPECT_EQ(delta_file_header_.size() + 0x62, i); break; } } diff --git a/src/vcdecoder_test.h b/src/vcdecoder_test.h index 59ba703..2967444 100644 --- a/src/vcdecoder_test.h +++ b/src/vcdecoder_test.h @@ -29,9 +29,7 @@ namespace open_vcdiff { // overwritten by each specific decoder test as needed. class VCDiffDecoderTest : public testing::Test { protected: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING static const char kDictionary[]; static const char kExpectedTarget[]; diff --git a/src/vcdiff_main.cc b/src/vcdiff_main.cc index d1500df..11e7304 100644 --- a/src/vcdiff_main.cc +++ b/src/vcdiff_main.cc @@ -32,9 +32,9 @@ #include "google/vcdecoder.h" #include "google/vcencoder.h" -#ifndef VCDIFF_HAS_GLOBAL_STRING +#ifndef HAS_GLOBAL_STRING using std::string; -#endif // !VCDIFF_HAS_GLOBAL_STRING +#endif // !HAS_GLOBAL_STRING using google::GetCommandLineFlagInfoOrDie; using google::ShowUsageWithFlagsRestrict; diff --git a/src/vcdiffengine_test.cc b/src/vcdiffengine_test.cc index f122395..94a36b5 100644 --- a/src/vcdiffengine_test.cc +++ b/src/vcdiffengine_test.cc @@ -34,9 +34,7 @@ namespace { class VCDiffEngineTestBase : public testing::Test { protected: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING // Some common definitions and helper functions used in the various tests // for VCDiffEngine. diff --git a/src/vcencoder_test.cc b/src/vcencoder_test.cc index b32c42a..64f1c08 100644 --- a/src/vcencoder_test.cc +++ b/src/vcencoder_test.cc @@ -22,7 +22,6 @@ #include <vector> #include "blockhash.h" #include "checksum.h" -#include "google/output_string.h" #include "testing.h" #include "varint_bigendian.h" #include "google/vcdecoder.h" @@ -65,9 +64,7 @@ static const size_t kWindowHeaderSize = 21; class VerifyEncodedBytesTest : public testing::Test { public: -#ifndef VCDIFF_HAS_GLOBAL_STRING typedef std::string string; -#endif // !VCDIFF_HAS_GLOBAL_STRING VerifyEncodedBytesTest() : delta_index_(0) { } virtual ~VerifyEncodedBytesTest() { } diff --git a/vsprojects/config.h b/vsprojects/config.h index 0c5ef01..9840cdb 100644 --- a/vsprojects/config.h +++ b/vsprojects/config.h @@ -45,19 +45,19 @@ #define PACKAGE_NAME "open-vcdiff" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "open-vcdiff 0.6" +#define PACKAGE_STRING "open-vcdiff 0.7" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "open-vcdiff" /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.6" +#define PACKAGE_VERSION "0.7" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "0.6" +#define VERSION "0.7" // These functions have different names, but the same behavior, // for Visual Studio. |