From 414ec1b386f021880a8b9922249594afe8fdad2c Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 22 Jun 2004 15:23:05 +0000 Subject: [PATCH] more range checking --- direct/src/dcparser/dcArrayParameter.h | 2 +- direct/src/dcparser/dcAtomicField.h | 2 +- direct/src/dcparser/dcClass.h | 2 +- direct/src/dcparser/dcClassParameter.h | 2 +- direct/src/dcparser/dcField.cxx | 38 +- direct/src/dcparser/dcField.h | 4 +- direct/src/dcparser/dcFile.h | 2 +- direct/src/dcparser/dcMolecularField.h | 2 +- direct/src/dcparser/dcNumericRange.I | 31 + direct/src/dcparser/dcNumericRange.h | 4 + direct/src/dcparser/dcPacker.I | 87 +- direct/src/dcparser/dcPacker.cxx | 53 +- direct/src/dcparser/dcPacker.h | 3 + direct/src/dcparser/dcPackerInterface.I | 103 +- direct/src/dcparser/dcPackerInterface.cxx | 111 ++- direct/src/dcparser/dcPackerInterface.h | 65 +- direct/src/dcparser/dcParameter.h | 2 +- direct/src/dcparser/dcParser.cxx.prebuilt | 154 +-- direct/src/dcparser/dcParser.yxx | 12 +- direct/src/dcparser/dcSimpleParameter.cxx | 1047 +++++++++++++++------ direct/src/dcparser/dcSimpleParameter.h | 42 +- 21 files changed, 1214 insertions(+), 554 deletions(-) diff --git a/direct/src/dcparser/dcArrayParameter.h b/direct/src/dcparser/dcArrayParameter.h index 5b6e93804b..0e8612b163 100644 --- a/direct/src/dcparser/dcArrayParameter.h +++ b/direct/src/dcparser/dcArrayParameter.h @@ -49,7 +49,7 @@ public: virtual void output_instance(ostream &out, const string &prename, const string &name, const string &postname) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; private: DCParameter *_element_type; diff --git a/direct/src/dcparser/dcAtomicField.h b/direct/src/dcparser/dcAtomicField.h index dd1f6879fa..f61a248fa9 100644 --- a/direct/src/dcparser/dcAtomicField.h +++ b/direct/src/dcparser/dcAtomicField.h @@ -64,7 +64,7 @@ PUBLISHED: public: DCAtomicField(const string &name); virtual void write(ostream &out, bool brief, int indent_level) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; virtual DCPackerInterface *get_nested_field(int n) const; diff --git a/direct/src/dcparser/dcClass.h b/direct/src/dcparser/dcClass.h index 0d1b20d146..d478f8a921 100644 --- a/direct/src/dcparser/dcClass.h +++ b/direct/src/dcparser/dcClass.h @@ -86,7 +86,7 @@ public: ~DCClass(); virtual void write(ostream &out, bool brief, int indent_level) const; - void generate_hash(HashGenerator &hash) const; + void generate_hash(HashGenerator &hashgen) const; bool add_field(DCField *field); bool add_parameter(DCParameter *parameter); diff --git a/direct/src/dcparser/dcClassParameter.h b/direct/src/dcparser/dcClassParameter.h index 48e0f26c9f..d823f3c947 100644 --- a/direct/src/dcparser/dcClassParameter.h +++ b/direct/src/dcparser/dcClassParameter.h @@ -47,7 +47,7 @@ public: virtual void output_instance(ostream &out, const string &prename, const string &name, const string &postname) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; private: DCClass *_dclass; diff --git a/direct/src/dcparser/dcField.cxx b/direct/src/dcparser/dcField.cxx index 87d3e5ff2d..176044b53d 100644 --- a/direct/src/dcparser/dcField.cxx +++ b/direct/src/dcparser/dcField.cxx @@ -100,6 +100,26 @@ parse_string(const string &formatted_string) { return packer.get_string(); } +//////////////////////////////////////////////////////////////////// +// Function: DCField::validate_ranges +// Access: Published +// Description: Verifies that all of the packed values in the field +// data are within the specified ranges and that there +// are no extra bytes on the end of the record. Returns +// true if all fields are valid, false otherwise. +//////////////////////////////////////////////////////////////////// +bool DCField:: +validate_ranges(const string &packed_data) const { + DCPacker packer; + packer.begin_unpack(packed_data, this); + packer.unpack_validate(); + if (!packer.end_unpack()) { + return false; + } + + return (packer.get_num_unpacked_bytes() == packed_data.length()); +} + #ifdef HAVE_PYTHON //////////////////////////////////////////////////////////////////// // Function: DCField::pack_args @@ -130,8 +150,13 @@ pack_args(Datagram &datagram, PyObject *sequence) const { PyObject *str = PyObject_Str(tuple); ostringstream strm; - strm << "Incorrect arguments or value out of range on field: " << get_name() - << PyString_AsString(str); + if (packer.had_pack_error()) { + strm << "Incorrect arguments to field: " << get_name() + << PyString_AsString(str); + } else { + strm << "Value out of range on field: " << get_name() + << PyString_AsString(str); + } Py_DECREF(str); Py_DECREF(tuple); @@ -172,7 +197,14 @@ unpack_args(DatagramIterator &iterator) const { } ostringstream strm; - strm << "Error unpacking field " << get_name(); + if (packer.had_pack_error()) { + strm << "Error unpacking to field " << get_name(); + } else { + PyObject *str = PyObject_Str(object); + strm << "Found value outside specified range when unpacking field " + << get_name() << ": " << PyString_AsString(str); + Py_DECREF(str); + } nassert_raise(strm.str()); return object; diff --git a/direct/src/dcparser/dcField.h b/direct/src/dcparser/dcField.h index 367bd5c068..e4ae6f0b79 100644 --- a/direct/src/dcparser/dcField.h +++ b/direct/src/dcparser/dcField.h @@ -52,6 +52,8 @@ PUBLISHED: string format_data(const string &packed_data); string parse_string(const string &formatted_string); + bool validate_ranges(const string &packed_data) const; + #ifdef HAVE_PYTHON bool pack_args(Datagram &datagram, PyObject *sequence) const; PyObject *unpack_args(DatagramIterator &iterator) const; @@ -66,7 +68,7 @@ public: DCField(const string &name); virtual ~DCField(); virtual void write(ostream &out, bool brief, int indent_level) const=0; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; void set_number(int number); diff --git a/direct/src/dcparser/dcFile.h b/direct/src/dcparser/dcFile.h index 598c76f2f2..c276124355 100644 --- a/direct/src/dcparser/dcFile.h +++ b/direct/src/dcparser/dcFile.h @@ -66,7 +66,7 @@ PUBLISHED: unsigned long get_hash() const; public: - void generate_hash(HashGenerator &hash) const; + void generate_hash(HashGenerator &hashgen) const; bool add_class(DCClass *dclass); void add_import_module(const string &import_module); void add_import_symbol(const string &import_symbol); diff --git a/direct/src/dcparser/dcMolecularField.h b/direct/src/dcparser/dcMolecularField.h index f1411209a1..f3ada2e115 100644 --- a/direct/src/dcparser/dcMolecularField.h +++ b/direct/src/dcparser/dcMolecularField.h @@ -44,7 +44,7 @@ public: void add_atomic(DCAtomicField *atomic); virtual void write(ostream &out, bool brief, int indent_level) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; virtual DCPackerInterface *get_nested_field(int n) const; diff --git a/direct/src/dcparser/dcNumericRange.I b/direct/src/dcparser/dcNumericRange.I index 481724e5b4..c71ae5743d 100644 --- a/direct/src/dcparser/dcNumericRange.I +++ b/direct/src/dcparser/dcNumericRange.I @@ -27,6 +27,17 @@ INLINE DCNumericRange:: DCNumericRange() { } +//////////////////////////////////////////////////////////////////// +// Function: DCNumericRange::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE DCNumericRange:: +DCNumericRange(Number min, Number max) { + add_range(min, max); +} + //////////////////////////////////////////////////////////////////// // Function: DCNumericRange::Copy Constructor // Access: Public @@ -89,6 +100,26 @@ validate(Number num, bool &validation_error) const { } } +//////////////////////////////////////////////////////////////////// +// Function: DCNumericRange::generate_hash +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +void DCNumericRange:: +generate_hash(HashGenerator &hashgen) const { + if (!_ranges.empty()) { + hashgen.add_int(_ranges.size()); + TYPENAME Ranges::const_iterator ri; + for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) { + // We don't account for the fractional part of floating-point + // ranges here. Shouldn't be a real issue. + hashgen.add_int((int)(*ri)._min); + hashgen.add_int((int)(*ri)._max); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: DCNumericRange::output // Access: Public diff --git a/direct/src/dcparser/dcNumericRange.h b/direct/src/dcparser/dcNumericRange.h index 0b4c446805..f5257fbb24 100644 --- a/direct/src/dcparser/dcNumericRange.h +++ b/direct/src/dcparser/dcNumericRange.h @@ -20,6 +20,7 @@ #define DCNUMERICRANGE_H #include "dcbase.h" +#include "hashGenerator.h" //////////////////////////////////////////////////////////////////// // Class : DCNumericRange @@ -33,12 +34,15 @@ public: typedef NUM Number; INLINE DCNumericRange(); + INLINE DCNumericRange(Number min, Number max); INLINE DCNumericRange(const DCNumericRange ©); INLINE void operator = (const DCNumericRange ©); bool is_in_range(Number num) const; INLINE void validate(Number num, bool &validation_error) const; + void generate_hash(HashGenerator &hashgen) const; + void output(ostream &out, Number divisor = 1) const; public: diff --git a/direct/src/dcparser/dcPacker.I b/direct/src/dcparser/dcPacker.I index ca349f62ac..908292a2b3 100755 --- a/direct/src/dcparser/dcPacker.I +++ b/direct/src/dcparser/dcPacker.I @@ -110,9 +110,7 @@ pack_double(double value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_double(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_double(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -129,9 +127,7 @@ pack_int(int value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_int(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_int(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -148,9 +144,7 @@ pack_uint(unsigned int value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_uint(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_uint(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -167,9 +161,7 @@ pack_int64(PN_int64 value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_int64(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_int64(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -186,9 +178,7 @@ pack_uint64(PN_uint64 value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_uint64(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_uint64(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -205,9 +195,7 @@ pack_string(const string &value) { if (_current_field == NULL) { _pack_error = true; } else { - if (!_current_field->pack_string(_pack_data, value)) { - _pack_error = true; - } + _current_field->pack_string(_pack_data, value, _pack_error, _range_error); advance(); } } @@ -244,9 +232,8 @@ unpack_double() { _pack_error = true; } else { - if (!_current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -267,9 +254,8 @@ unpack_int() { _pack_error = true; } else { - if (!_current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -290,9 +276,8 @@ unpack_uint() { _pack_error = true; } else { - if (!_current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -313,9 +298,8 @@ unpack_int64() { _pack_error = true; } else { - if (!_current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -336,9 +320,8 @@ unpack_uint64() { _pack_error = true; } else { - if (!_current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -359,9 +342,8 @@ unpack_string() { _pack_error = true; } else { - if (!_current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p, value)) { - _pack_error = true; - } + _current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p, + value, _pack_error, _range_error); advance(); } @@ -386,16 +368,41 @@ unpack_literal_value() { //////////////////////////////////////////////////////////////////// // Function: DCPacker::had_pack_error // Access: Published -// Description: Returns true if there has been an error in packing -// since the most recent call to begin(). It is -// most useful to call this after end() to validate -// the entire packing run. +// Description: Returns true if there has been an packing error +// since the most recent call to begin(); in particular, +// this may be called after end() has returned false to +// determine the nature of the failure. +// +// A return value of true indicates there was a push/pop +// mismatch, or the push/pop structure did not match the +// data structure, or there were the wrong number of +// elements in a nested push/pop structure, or on unpack +// that the data stream was truncated. //////////////////////////////////////////////////////////////////// INLINE bool DCPacker:: had_pack_error() const { return _pack_error; } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::had_range_error +// Access: Published +// Description: Returns true if there has been an range validation +// error since the most recent call to begin(); in +// particular, this may be called after end() has +// returned false to determine the nature of the +// failure. +// +// A return value of true indicates a value that was +// packed or unpacked did not fit within the specified +// legal range for a parameter, or within the limits of +// the field size. +//////////////////////////////////////////////////////////////////// +INLINE bool DCPacker:: +had_range_error() const { + return _range_error; +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::get_num_unpacked_bytes // Access: Published diff --git a/direct/src/dcparser/dcPacker.cxx b/direct/src/dcparser/dcPacker.cxx index 5d7ce72eb6..83952c6fa8 100755 --- a/direct/src/dcparser/dcPacker.cxx +++ b/direct/src/dcparser/dcPacker.cxx @@ -40,6 +40,7 @@ DCPacker() { _current_field_index = 0; _num_nested_fields = 0; _pack_error = false; + _range_error = false; } //////////////////////////////////////////////////////////////////// @@ -65,6 +66,7 @@ begin_pack(const DCPackerInterface *root) { _mode = M_pack; _pack_error = false; + _range_error = false; _pack_data.clear(); _root = root; @@ -97,7 +99,7 @@ end_pack() { clear(); - return !_pack_error; + return !_pack_error && !_range_error; } //////////////////////////////////////////////////////////////////// @@ -128,6 +130,7 @@ begin_unpack(const char *data, size_t length, _mode = M_unpack; _pack_error = false; + _range_error = false; set_unpack_data(data, length, false); _unpack_p = 0; @@ -170,7 +173,7 @@ end_unpack() { clear(); - return !_pack_error; + return !_pack_error && !_range_error; } //////////////////////////////////////////////////////////////////// @@ -208,6 +211,7 @@ begin_repack(const char *data, size_t length, _mode = M_repack; _pack_error = false; + _range_error = false; set_unpack_data(data, length, false); _unpack_p = 0; @@ -244,7 +248,7 @@ end_repack() { _mode = M_idle; clear(); - return !_pack_error; + return !_pack_error && !_range_error; } //////////////////////////////////////////////////////////////////// @@ -429,7 +433,6 @@ push() { } else { _current_field = _current_parent->get_nested_field(_current_field_index); } - } } @@ -467,12 +470,11 @@ pop() { size_t length = _pack_data.get_length() - _push_marker - length_bytes; if (length_bytes == 4) { DCPackerInterface::do_pack_uint32 - (_pack_data.get_rewrite_pointer(_push_marker, 4), length, - _pack_error); + (_pack_data.get_rewrite_pointer(_push_marker, 4), length); } else { + DCPackerInterface::validate_uint_limits(length, 16, _range_error); DCPackerInterface::do_pack_uint16 - (_pack_data.get_rewrite_pointer(_push_marker, 2), length, - _pack_error); + (_pack_data.get_rewrite_pointer(_push_marker, 2), length); } } } @@ -488,13 +490,44 @@ pop() { advance(); } +//////////////////////////////////////////////////////////////////// +// Function: DCPacker::unpack_validate +// Access: Published +// Description: Internally unpacks the current numeric or string +// value and validates it against the type range limits, +// but does not return the value. If the current field +// contains nested fields, validates all of them. +//////////////////////////////////////////////////////////////////// +void DCPacker:: +unpack_validate() { + nassertv(_mode == M_unpack); + if (_current_field == NULL) { + _pack_error = true; + + } else { + if (_current_field->unpack_validate(_unpack_data, _unpack_length, _unpack_p, + _pack_error, _range_error)) { + advance(); + } else { + // If the single field couldn't be validated, try validating + // nested fields. + push(); + while (more_nested_fields()) { + unpack_validate(); + } + pop(); + } + } +} + //////////////////////////////////////////////////////////////////// // Function: DCPacker::unpack_skip // Access: Published // Description: Skips the current field without unpacking it and -// advances to the next field. +// advances to the next field. If the current field +// contains nested fields, skips all of them. //////////////////////////////////////////////////////////////////// -INLINE void DCPacker:: +void DCPacker:: unpack_skip() { nassertv(_mode == M_unpack); if (_current_field == NULL) { diff --git a/direct/src/dcparser/dcPacker.h b/direct/src/dcparser/dcPacker.h index 027f17a595..5c707d6573 100755 --- a/direct/src/dcparser/dcPacker.h +++ b/direct/src/dcparser/dcPacker.h @@ -80,6 +80,7 @@ PUBLISHED: INLINE PN_uint64 unpack_uint64(); INLINE string unpack_string(); INLINE string unpack_literal_value(); + INLINE void unpack_validate(); void unpack_skip(); #ifdef HAVE_PYTHON @@ -93,6 +94,7 @@ PUBLISHED: void unpack_and_format(ostream &out); INLINE bool had_pack_error() const; + INLINE bool had_range_error() const; INLINE size_t get_num_unpacked_bytes() const; INLINE string get_string() const; @@ -147,6 +149,7 @@ private: int _num_nested_fields; bool _pack_error; + bool _range_error; }; #include "dcPacker.I" diff --git a/direct/src/dcparser/dcPackerInterface.I b/direct/src/dcparser/dcPackerInterface.I index c4f7e08c40..7167cfead2 100644 --- a/direct/src/dcparser/dcPackerInterface.I +++ b/direct/src/dcparser/dcPackerInterface.I @@ -117,11 +117,8 @@ get_pack_type() const { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_int8(char *buffer, int value, bool &pack_error) { +do_pack_int8(char *buffer, int value) { buffer[0] = (char)(value & 0xff); - if ((abs(value) & ~0xff) != 0) { - pack_error = true; - } } //////////////////////////////////////////////////////////////////// @@ -130,12 +127,9 @@ do_pack_int8(char *buffer, int value, bool &pack_error) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_int16(char *buffer, int value, bool &pack_error) { +do_pack_int16(char *buffer, int value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); - if ((abs(value) & ~0xffff) != 0) { - pack_error = true; - } } //////////////////////////////////////////////////////////////////// @@ -144,7 +138,7 @@ do_pack_int16(char *buffer, int value, bool &pack_error) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_int32(char *buffer, int value, bool &) { +do_pack_int32(char *buffer, int value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); buffer[2] = (char)((value >> 16) & 0xff); @@ -157,7 +151,7 @@ do_pack_int32(char *buffer, int value, bool &) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_int64(char *buffer, PN_int64 value, bool &) { +do_pack_int64(char *buffer, PN_int64 value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); buffer[2] = (char)((value >> 16) & 0xff); @@ -174,11 +168,8 @@ do_pack_int64(char *buffer, PN_int64 value, bool &) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_uint8(char *buffer, unsigned int value, bool &pack_error) { +do_pack_uint8(char *buffer, unsigned int value) { buffer[0] = (char)(value & 0xff); - if ((value & ~0xff) != 0) { - pack_error = true; - } } //////////////////////////////////////////////////////////////////// @@ -187,12 +178,9 @@ do_pack_uint8(char *buffer, unsigned int value, bool &pack_error) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_uint16(char *buffer, unsigned int value, bool &pack_error) { +do_pack_uint16(char *buffer, unsigned int value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); - if ((value & ~0xffff) != 0) { - pack_error = true; - } } //////////////////////////////////////////////////////////////////// @@ -201,7 +189,7 @@ do_pack_uint16(char *buffer, unsigned int value, bool &pack_error) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_uint32(char *buffer, unsigned int value, bool &) { +do_pack_uint32(char *buffer, unsigned int value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); buffer[2] = (char)((value >> 16) & 0xff); @@ -214,7 +202,7 @@ do_pack_uint32(char *buffer, unsigned int value, bool &) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_uint64(char *buffer, PN_uint64 value, bool &) { +do_pack_uint64(char *buffer, PN_uint64 value) { buffer[0] = (char)(value & 0xff); buffer[1] = (char)((value >> 8) & 0xff); buffer[2] = (char)((value >> 16) & 0xff); @@ -231,7 +219,7 @@ do_pack_uint64(char *buffer, PN_uint64 value, bool &) { // Description: //////////////////////////////////////////////////////////////////// INLINE void DCPackerInterface:: -do_pack_float64(char *buffer, double value, bool &) { +do_pack_float64(char *buffer, double value) { #ifdef WORDS_BIGENDIAN // Reverse the byte ordering for big-endian machines. char *p = (char *)value; @@ -365,3 +353,76 @@ do_unpack_float64(const char *buffer) { return *(double *)buffer; #endif // WORDS_BIGENDIAN } + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::validate_int_limits +// Access: Public, Static +// Description: Confirms that the signed value fits within num_bits +// bits. Sets range_error true if it does not. +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +validate_int_limits(int value, int num_bits, bool &range_error) { + // What we're really checking is that all of the bits above the + // lower (num_bits - 1) bits are the same--either all 1 or all 0. + + // First, turn on the lower (num_bits - 1). + int mask = ((int)1 << (num_bits - 1)) - 1; + value |= mask; + + // The result should be either mask (all high bits are 0) or -1 (all + // high bits are 1). If it is anything else we have a range error. + if (value != mask && value != -1) { + range_error = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::validate_int64_limits +// Access: Public, Static +// Description: Confirms that the signed value fits within num_bits +// bits. Sets range_error true if it does not. +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +validate_int64_limits(PN_int64 value, int num_bits, bool &range_error) { + PN_int64 mask = ((PN_int64)1 << (num_bits - 1)) - 1; + value |= mask; + + if (value != mask && value != -1) { + range_error = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::validate_uint_limits +// Access: Public, Static +// Description: Confirms that the unsigned value fits within num_bits +// bits. Sets range_error true if it does not. +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +validate_uint_limits(unsigned int value, int num_bits, bool &range_error) { + // Here we're really checking that all of the bits above the lower + // num_bits bits are all 0. + + unsigned int mask = ((unsigned int)1 << num_bits) - 1; + value &= ~mask; + + if (value != 0) { + range_error = true; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::validate_uint64_limits +// Access: Public, Static +// Description: Confirms that the unsigned value fits within num_bits +// bits. Sets range_error true if it does not. +//////////////////////////////////////////////////////////////////// +INLINE void DCPackerInterface:: +validate_uint64_limits(PN_uint64 value, int num_bits, bool &range_error) { + PN_uint64 mask = ((PN_uint64)1 << num_bits) - 1; + value &= ~mask; + + if (value != 0) { + range_error = true; + } +} diff --git a/direct/src/dcparser/dcPackerInterface.cxx b/direct/src/dcparser/dcPackerInterface.cxx index 5344b5df26..9c1422b80c 100755 --- a/direct/src/dcparser/dcPackerInterface.cxx +++ b/direct/src/dcparser/dcPackerInterface.cxx @@ -99,131 +99,145 @@ get_nested_field(int n) const { // Function: DCPackerInterface::pack_double // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_double(DCPackData &, double) const { - return false; +void DCPackerInterface:: +pack_double(DCPackData &, double, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_int // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_int(DCPackData &, int) const { - return false; +void DCPackerInterface:: +pack_int(DCPackData &, int, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_uint // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_uint(DCPackData &, unsigned int) const { - return false; +void DCPackerInterface:: +pack_uint(DCPackData &, unsigned int, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_int64 // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_int64(DCPackData &, PN_int64) const { - return false; +void DCPackerInterface:: +pack_int64(DCPackData &, PN_int64, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_uint64 // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_uint64(DCPackData &, PN_uint64) const { - return false; +void DCPackerInterface:: +pack_uint64(DCPackData &, PN_uint64, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::pack_string // Access: Public, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -pack_string(DCPackData &, const string &) const { - return false; +void DCPackerInterface:: +pack_string(DCPackData &, const string &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_double // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -unpack_double(const char *, size_t, size_t &, double &) const { - return false; +void DCPackerInterface:: +unpack_double(const char *, size_t, size_t &, double &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_int // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -unpack_int(const char *, size_t, size_t &, int &) const { - return false; +void DCPackerInterface:: +unpack_int(const char *, size_t, size_t &, int &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_uint // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -unpack_uint(const char *, size_t, size_t &, unsigned int &) const { - return false; +void DCPackerInterface:: +unpack_uint(const char *, size_t, size_t &, unsigned int &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_int64 // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -unpack_int64(const char *, size_t, size_t &, PN_int64 &) const { - return false; +void DCPackerInterface:: +unpack_int64(const char *, size_t, size_t &, PN_int64 &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_uint64 // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCPackerInterface:: -unpack_uint64(const char *, size_t, size_t &, PN_uint64 &) const { - return false; +void DCPackerInterface:: +unpack_uint64(const char *, size_t, size_t &, PN_uint64 &, bool &pack_error, bool &) const { + pack_error = true; } //////////////////////////////////////////////////////////////////// // Function: DCPackerInterface::unpack_string // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. +//////////////////////////////////////////////////////////////////// +void DCPackerInterface:: +unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool &) const { + pack_error = true; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCPackerInterface::unpack_validate +// Access: Public, Virtual +// Description: Internally unpacks the current numeric or string +// value and validates it against the type range limits, +// but does not return the value. Returns true on +// success, false on failure (e.g. we don't know how to +// validate this field). //////////////////////////////////////////////////////////////////// bool DCPackerInterface:: -unpack_string(const char *, size_t, size_t &, string &) const { +unpack_validate(const char *, size_t, size_t &, bool &, bool &) const { return false; } @@ -231,8 +245,9 @@ unpack_string(const char *, size_t, size_t &, string &) const { // Function: DCPackerInterface::unpack_skip // Access: Public, Virtual // Description: Increments p to the end of the current field without -// actually unpacking any data. Returns true on -// success, false on failure. +// actually unpacking any data or performing any range +// validation. Returns true on success, false on +// failure (e.g. we don't know how to skip this field). //////////////////////////////////////////////////////////////////// bool DCPackerInterface:: unpack_skip(const char *, size_t, size_t &) const { diff --git a/direct/src/dcparser/dcPackerInterface.h b/direct/src/dcparser/dcPackerInterface.h index ea903c06b7..4ed421bf30 100755 --- a/direct/src/dcparser/dcPackerInterface.h +++ b/direct/src/dcparser/dcPackerInterface.h @@ -83,33 +83,47 @@ public: INLINE DCPackType get_pack_type() const; - virtual bool pack_double(DCPackData &pack_data, double value) const; - virtual bool pack_int(DCPackData &pack_data, int value) const; - virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; - virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; - virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; - virtual bool pack_string(DCPackData &pack_data, const string &value) const; + virtual void pack_double(DCPackData &pack_data, double value, + bool &pack_error, bool &range_error) const; + virtual void pack_int(DCPackData &pack_data, int value, + bool &pack_error, bool &range_error) const; + virtual void pack_uint(DCPackData &pack_data, unsigned int value, + bool &pack_error, bool &range_error) const; + virtual void pack_int64(DCPackData &pack_data, PN_int64 value, + bool &pack_error, bool &range_error) const; + virtual void pack_uint64(DCPackData &pack_data, PN_uint64 value, + bool &pack_error, bool &range_error) const; + virtual void pack_string(DCPackData &pack_data, const string &value, + bool &pack_error, bool &range_error) const; - virtual bool unpack_double(const char *data, size_t length, size_t &p, double &value) const; - virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; - virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; - virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; - virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; - virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; + virtual void unpack_double(const char *data, size_t length, size_t &p, + double &value, bool &pack_error, bool &range_error) const; + virtual void unpack_int(const char *data, size_t length, size_t &p, + int &value, bool &pack_error, bool &range_error) const; + virtual void unpack_uint(const char *data, size_t length, size_t &p, + unsigned int &value, bool &pack_error, bool &range_error) const; + virtual void unpack_int64(const char *data, size_t length, size_t &p, + PN_int64 &value, bool &pack_error, bool &range_error) const; + virtual void unpack_uint64(const char *data, size_t length, size_t &p, + PN_uint64 &value, bool &pack_error, bool &range_error) const; + virtual void unpack_string(const char *data, size_t length, size_t &p, + string &value, bool &pack_error, bool &range_error) const; + virtual bool unpack_validate(const char *data, size_t length, size_t &p, + bool &pack_error, bool &range_error) const; virtual bool unpack_skip(const char *data, size_t length, size_t &p) const; // These are the low-level interfaces for packing and unpacking // numbers from a buffer. You're responsible for making sure the // buffer has enough room, and for incrementing the pointer. - INLINE static void do_pack_int8(char *buffer, int value, bool &pack_error); - INLINE static void do_pack_int16(char *buffer, int value, bool &pack_error); - INLINE static void do_pack_int32(char *buffer, int value, bool &pack_error); - INLINE static void do_pack_int64(char *buffer, PN_int64 value, bool &pack_error); - INLINE static void do_pack_uint8(char *buffer, unsigned int value, bool &pack_error); - INLINE static void do_pack_uint16(char *buffer, unsigned int value, bool &pack_error); - INLINE static void do_pack_uint32(char *buffer, unsigned int value, bool &pack_error); - INLINE static void do_pack_uint64(char *buffer, PN_uint64 value, bool &pack_error); - INLINE static void do_pack_float64(char *buffer, double value, bool &pack_error); + INLINE static void do_pack_int8(char *buffer, int value); + INLINE static void do_pack_int16(char *buffer, int value); + INLINE static void do_pack_int32(char *buffer, int value); + INLINE static void do_pack_int64(char *buffer, PN_int64 value); + INLINE static void do_pack_uint8(char *buffer, unsigned int value); + INLINE static void do_pack_uint16(char *buffer, unsigned int value); + INLINE static void do_pack_uint32(char *buffer, unsigned int value); + INLINE static void do_pack_uint64(char *buffer, PN_uint64 value); + INLINE static void do_pack_float64(char *buffer, double value); INLINE static int do_unpack_int8(const char *buffer); INLINE static int do_unpack_int16(const char *buffer); @@ -121,6 +135,15 @@ public: INLINE static PN_uint64 do_unpack_uint64(const char *buffer); INLINE static double do_unpack_float64(const char *buffer); + INLINE static void validate_int_limits(int value, int num_bits, + bool &range_error); + INLINE static void validate_int64_limits(PN_int64 value, int num_bits, + bool &range_error); + INLINE static void validate_uint_limits(unsigned int value, int num_bits, + bool &range_error); + INLINE static void validate_uint64_limits(PN_uint64 value, int num_bits, + bool &range_error); + const DCPackerCatalog *get_catalog() const; protected: diff --git a/direct/src/dcparser/dcParameter.h b/direct/src/dcparser/dcParameter.h index b46b86aebf..a3f87bd316 100644 --- a/direct/src/dcparser/dcParameter.h +++ b/direct/src/dcparser/dcParameter.h @@ -65,7 +65,7 @@ public: const string &name, const string &postname) const=0; void output_typedef_name(ostream &out, const string &prename, const string &name, const string &postname) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; private: const DCTypedef *_typedef; diff --git a/direct/src/dcparser/dcParser.cxx.prebuilt b/direct/src/dcparser/dcParser.cxx.prebuilt index b0f18e152d..ad14c478db 100644 --- a/direct/src/dcparser/dcParser.cxx.prebuilt +++ b/direct/src/dcparser/dcParser.cxx.prebuilt @@ -224,14 +224,14 @@ static const short yyrline[] = 207, 209, 215, 220, 226, 242, 244, 247, 254, 262, 264, 265, 266, 267, 271, 279, 279, 290, 306, 308, 311, 313, 316, 322, 322, 346, 346, 357, 361, 363, - 366, 371, 377, 388, 400, 412, 433, 438, 445, 452, - 462, 468, 474, 485, 487, 491, 497, 503, 517, 521, - 527, 532, 535, 540, 544, 548, 552, 552, 560, 560, - 568, 568, 576, 582, 588, 596, 598, 601, 603, 606, - 608, 611, 616, 620, 624, 628, 632, 636, 640, 644, - 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, - 690, 692, 696, 700, 704, 708, 712, 716, 720, 724, - 730, 730, 741, 748, 761 + 366, 371, 379, 390, 404, 418, 439, 444, 451, 458, + 468, 474, 480, 491, 493, 497, 503, 509, 523, 527, + 533, 538, 541, 546, 550, 554, 558, 558, 566, 566, + 574, 574, 582, 588, 594, 602, 604, 607, 609, 612, + 614, 617, 622, 626, 630, 634, 638, 642, 646, 650, + 654, 658, 662, 666, 670, 674, 678, 682, 686, 690, + 696, 698, 702, 706, 710, 714, 718, 722, 726, 730, + 736, 736, 747, 754, 767 }; #endif @@ -1321,12 +1321,14 @@ case 51: #line 372 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-3].u.subatomic); - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } yyval.u.parameter = simple_param; } break; case 52: -#line 378 "dcParser.yxx" +#line 380 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-2].u.subatomic); if (yyvsp[0].u.integer == 0) { @@ -1339,7 +1341,7 @@ case 52: } break; case 53: -#line 389 "dcParser.yxx" +#line 391 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[-3].u.integer == 0) { @@ -1348,12 +1350,14 @@ case 53: } else if (!simple_param->set_divisor(yyvsp[-3].u.integer)) { yyerror("A divisor is only valid on a numeric type."); } - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } yyval.u.parameter = simple_param; } break; case 54: -#line 401 "dcParser.yxx" +#line 405 "dcParser.yxx" { DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); if (yyvsp[0].u.integer == 0) { @@ -1362,12 +1366,14 @@ case 54: } else if (!simple_param->set_divisor(yyvsp[0].u.integer)) { yyerror("A divisor is only valid on a numeric type."); } - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } yyval.u.parameter = simple_param; } break; case 55: -#line 413 "dcParser.yxx" +#line 419 "dcParser.yxx" { DCTypedef *dtypedef = dc_file->get_typedef_by_name(yyvsp[0].str); if (dtypedef == (DCTypedef *)NULL) { @@ -1388,13 +1394,13 @@ case 55: } break; case 56: -#line 435 "dcParser.yxx" +#line 441 "dcParser.yxx" { double_range.clear(); } break; case 57: -#line 439 "dcParser.yxx" +#line 445 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { @@ -1403,7 +1409,7 @@ case 57: } break; case 58: -#line 446 "dcParser.yxx" +#line 452 "dcParser.yxx" { double_range.clear(); if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { @@ -1412,7 +1418,7 @@ case 58: } break; case 59: -#line 453 "dcParser.yxx" +#line 459 "dcParser.yxx" { double_range.clear(); if (yyvsp[0].u.real >= 0) { @@ -1424,7 +1430,7 @@ case 59: } break; case 60: -#line 463 "dcParser.yxx" +#line 469 "dcParser.yxx" { if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { yyerror("Overlapping range"); @@ -1432,7 +1438,7 @@ case 60: } break; case 61: -#line 469 "dcParser.yxx" +#line 475 "dcParser.yxx" { if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { yyerror("Overlapping range"); @@ -1440,7 +1446,7 @@ case 61: } break; case 62: -#line 475 "dcParser.yxx" +#line 481 "dcParser.yxx" { if (yyvsp[0].u.real >= 0) { yyerror("Syntax error"); @@ -1451,26 +1457,26 @@ case 62: } break; case 64: -#line 488 "dcParser.yxx" +#line 494 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); } break; case 65: -#line 492 "dcParser.yxx" +#line 498 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); } break; case 66: -#line 499 "dcParser.yxx" +#line 505 "dcParser.yxx" { current_parameter->set_name(yyvsp[0].str); yyval.u.parameter = current_parameter; } break; case 67: -#line 504 "dcParser.yxx" +#line 510 "dcParser.yxx" { if (yyvsp[0].u.integer == 0) { yyerror("Invalid divisor."); @@ -1486,85 +1492,85 @@ case 67: } break; case 68: -#line 518 "dcParser.yxx" +#line 524 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); } break; case 69: -#line 522 "dcParser.yxx" +#line 528 "dcParser.yxx" { yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); } break; case 70: -#line 529 "dcParser.yxx" +#line 535 "dcParser.yxx" { yyval.u.real = (double)yyvsp[0].u.integer; } break; case 72: -#line 537 "dcParser.yxx" +#line 543 "dcParser.yxx" { current_packer->pack_int64(yyvsp[0].u.integer); } break; case 73: -#line 541 "dcParser.yxx" +#line 547 "dcParser.yxx" { current_packer->pack_double(yyvsp[0].u.real); } break; case 74: -#line 545 "dcParser.yxx" +#line 551 "dcParser.yxx" { current_packer->pack_string(yyvsp[0].str); } break; case 75: -#line 549 "dcParser.yxx" +#line 555 "dcParser.yxx" { current_packer->pack_literal_value(yyvsp[0].str); } break; case 76: -#line 553 "dcParser.yxx" +#line 559 "dcParser.yxx" { current_packer->push(); } break; case 77: -#line 557 "dcParser.yxx" +#line 563 "dcParser.yxx" { current_packer->pop(); } break; case 78: -#line 561 "dcParser.yxx" +#line 567 "dcParser.yxx" { current_packer->push(); } break; case 79: -#line 565 "dcParser.yxx" +#line 571 "dcParser.yxx" { current_packer->pop(); } break; case 80: -#line 569 "dcParser.yxx" +#line 575 "dcParser.yxx" { current_packer->push(); } break; case 81: -#line 573 "dcParser.yxx" +#line 579 "dcParser.yxx" { current_packer->pop(); } break; case 82: -#line 577 "dcParser.yxx" +#line 583 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_int64(yyvsp[-2].u.integer); @@ -1572,7 +1578,7 @@ case 82: } break; case 83: -#line 583 "dcParser.yxx" +#line 589 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_double(yyvsp[-2].u.real); @@ -1580,7 +1586,7 @@ case 83: } break; case 84: -#line 589 "dcParser.yxx" +#line 595 "dcParser.yxx" { for (int i = 0; i < yyvsp[0].u.integer; i++) { current_packer->pack_literal_value(yyvsp[-2].str); @@ -1588,175 +1594,175 @@ case 84: } break; case 91: -#line 613 "dcParser.yxx" +#line 619 "dcParser.yxx" { yyval.u.subatomic = ST_int8; } break; case 92: -#line 617 "dcParser.yxx" +#line 623 "dcParser.yxx" { yyval.u.subatomic = ST_int16; } break; case 93: -#line 621 "dcParser.yxx" +#line 627 "dcParser.yxx" { yyval.u.subatomic = ST_int32; } break; case 94: -#line 625 "dcParser.yxx" +#line 631 "dcParser.yxx" { yyval.u.subatomic = ST_int64; } break; case 95: -#line 629 "dcParser.yxx" +#line 635 "dcParser.yxx" { yyval.u.subatomic = ST_uint8; } break; case 96: -#line 633 "dcParser.yxx" +#line 639 "dcParser.yxx" { yyval.u.subatomic = ST_uint16; } break; case 97: -#line 637 "dcParser.yxx" +#line 643 "dcParser.yxx" { yyval.u.subatomic = ST_uint32; } break; case 98: -#line 641 "dcParser.yxx" +#line 647 "dcParser.yxx" { yyval.u.subatomic = ST_uint64; } break; case 99: -#line 645 "dcParser.yxx" +#line 651 "dcParser.yxx" { yyval.u.subatomic = ST_float64; } break; case 100: -#line 649 "dcParser.yxx" +#line 655 "dcParser.yxx" { yyval.u.subatomic = ST_string; } break; case 101: -#line 653 "dcParser.yxx" +#line 659 "dcParser.yxx" { yyval.u.subatomic = ST_blob; } break; case 102: -#line 657 "dcParser.yxx" +#line 663 "dcParser.yxx" { yyval.u.subatomic = ST_blob32; } break; case 103: -#line 661 "dcParser.yxx" +#line 667 "dcParser.yxx" { yyval.u.subatomic = ST_int8array; } break; case 104: -#line 665 "dcParser.yxx" +#line 671 "dcParser.yxx" { yyval.u.subatomic = ST_int16array; } break; case 105: -#line 669 "dcParser.yxx" +#line 675 "dcParser.yxx" { yyval.u.subatomic = ST_int32array; } break; case 106: -#line 673 "dcParser.yxx" +#line 679 "dcParser.yxx" { yyval.u.subatomic = ST_uint8array; } break; case 107: -#line 677 "dcParser.yxx" +#line 683 "dcParser.yxx" { yyval.u.subatomic = ST_uint16array; } break; case 108: -#line 681 "dcParser.yxx" +#line 687 "dcParser.yxx" { yyval.u.subatomic = ST_uint32array; } break; case 109: -#line 685 "dcParser.yxx" +#line 691 "dcParser.yxx" { yyval.u.subatomic = ST_uint32uint8array; } break; case 111: -#line 693 "dcParser.yxx" +#line 699 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_required); } break; case 112: -#line 697 "dcParser.yxx" +#line 703 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_broadcast); } break; case 113: -#line 701 "dcParser.yxx" +#line 707 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_p2p); } break; case 114: -#line 705 "dcParser.yxx" +#line 711 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_ram); } break; case 115: -#line 709 "dcParser.yxx" +#line 715 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_db); } break; case 116: -#line 713 "dcParser.yxx" +#line 719 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_clsend); } break; case 117: -#line 717 "dcParser.yxx" +#line 723 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_clrecv); } break; case 118: -#line 721 "dcParser.yxx" +#line 727 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_ownsend); } break; case 119: -#line 725 "dcParser.yxx" +#line 731 "dcParser.yxx" { current_atomic->add_flag(DCAtomicField::F_airecv); } break; case 120: -#line 732 "dcParser.yxx" +#line 738 "dcParser.yxx" { current_molecular = new DCMolecularField(yyvsp[-1].str); if (!current_class->add_field(current_molecular)) { @@ -1765,7 +1771,7 @@ case 120: } break; case 122: -#line 743 "dcParser.yxx" +#line 749 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); @@ -1773,7 +1779,7 @@ case 122: } break; case 123: -#line 749 "dcParser.yxx" +#line 755 "dcParser.yxx" { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { current_molecular->add_atomic(yyvsp[0].u.atomic); @@ -2018,4 +2024,4 @@ yyreturn: #endif return yyresult; } -#line 764 "dcParser.yxx" +#line 770 "dcParser.yxx" diff --git a/direct/src/dcparser/dcParser.yxx b/direct/src/dcparser/dcParser.yxx index 4b9f0ec112..5d78bdf2bf 100644 --- a/direct/src/dcparser/dcParser.yxx +++ b/direct/src/dcparser/dcParser.yxx @@ -371,7 +371,9 @@ type_name: | type_token '(' double_range ')' { DCSimpleParameter *simple_param = new DCSimpleParameter($1); - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } $$ = simple_param; } | type_token '/' INTEGER @@ -394,7 +396,9 @@ type_name: } else if (!simple_param->set_divisor($3)) { yyerror("A divisor is only valid on a numeric type."); } - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } $$ = simple_param; } | type_token '(' double_range ')' '/' INTEGER @@ -406,7 +410,9 @@ type_name: } else if (!simple_param->set_divisor($6)) { yyerror("A divisor is only valid on a numeric type."); } - simple_param->set_range(double_range); + if (!simple_param->set_range(double_range)) { + yyerror("Inappropriate range for type"); + } $$ = simple_param; } | IDENTIFIER diff --git a/direct/src/dcparser/dcSimpleParameter.cxx b/direct/src/dcparser/dcSimpleParameter.cxx index 2697acedee..91e3e2ac7d 100644 --- a/direct/src/dcparser/dcSimpleParameter.cxx +++ b/direct/src/dcparser/dcSimpleParameter.cxx @@ -290,17 +290,43 @@ set_divisor(int divisor) { // Description: Sets the parameter with the indicated range. A // DCDoubleRange is used for specification, since this // is the most generic type; but it is converted to the -// appropriate type internally. +// appropriate type internally. The return value is +// true if successful, or false if the range is +// inappropriate for the type. //////////////////////////////////////////////////////////////////// -void DCSimpleParameter:: +bool DCSimpleParameter:: set_range(const DCDoubleRange &range) { + bool range_error = false; int num_ranges = range.get_num_ranges(); int i; switch (_type) { case ST_int8: + case ST_int8array: + _int_range.clear(); + for (i = 0; i < num_ranges; i++) { + int min = (int)floor(range.get_min(i) * _divisor + 0.5); + int max = (int)floor(range.get_max(i) * _divisor + 0.5); + validate_int_limits(min, 8, range_error); + validate_int_limits(max, 8, range_error); + _int_range.add_range(min, max); + } + break; + case ST_int16: + case ST_int16array: + _int_range.clear(); + for (i = 0; i < num_ranges; i++) { + int min = (int)floor(range.get_min(i) * _divisor + 0.5); + int max = (int)floor(range.get_max(i) * _divisor + 0.5); + validate_int_limits(min, 16, range_error); + validate_int_limits(max, 16, range_error); + _int_range.add_range(min, max); + } + break; + case ST_int32: + case ST_int32array: _int_range.clear(); for (i = 0; i < num_ranges; i++) { int min = (int)floor(range.get_min(i) * _divisor + 0.5); @@ -319,8 +345,34 @@ set_range(const DCDoubleRange &range) { break; case ST_uint8: + case ST_uint8array: + _uint_range.clear(); + for (i = 0; i < num_ranges; i++) { + unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); + unsigned int max = (unsigned int)floor(range.get_max(i) * _divisor + 0.5); + validate_uint_limits(min, 8, range_error); + validate_uint_limits(max, 8, range_error); + _uint_range.add_range(min, max); + } + break; + case ST_uint16: + case ST_uint16array: + case ST_string: + case ST_blob: + _uint_range.clear(); + for (i = 0; i < num_ranges; i++) { + unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); + unsigned int max = (unsigned int)floor(range.get_max(i) * _divisor + 0.5); + validate_uint_limits(min, 16, range_error); + validate_uint_limits(max, 16, range_error); + _uint_range.add_range(min, max); + } + break; + case ST_uint32: + case ST_uint32array: + case ST_blob32: _uint_range.clear(); for (i = 0; i < num_ranges; i++) { unsigned int min = (unsigned int)floor(range.get_min(i) * _divisor + 0.5); @@ -348,8 +400,10 @@ set_range(const DCDoubleRange &range) { break; default: - break; + return false; } + + return !range_error; } //////////////////////////////////////////////////////////////////// @@ -387,854 +441,1059 @@ get_nested_field(int) const { // Function: DCSimpleParameter::pack_double // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_double(DCPackData &pack_data, double value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_double(DCPackData &pack_data, double value, + bool &pack_error, bool &range_error) const { double real_value = value * _divisor; switch (_type) { case ST_int8: { int int_value = (int)floor(real_value + 0.5); - _int_range.validate(int_value, pack_error); - do_pack_int8(pack_data.get_write_pointer(1), int_value, pack_error); + _int_range.validate(int_value, range_error); + validate_int_limits(int_value, 8, range_error); + do_pack_int8(pack_data.get_write_pointer(1), int_value); } break; case ST_int16: { int int_value = (int)floor(real_value + 0.5); - _int_range.validate(int_value, pack_error); - do_pack_int16(pack_data.get_write_pointer(2), int_value, pack_error); + _int_range.validate(int_value, range_error); + validate_int_limits(int_value, 16, range_error); + do_pack_int16(pack_data.get_write_pointer(2), int_value); } break; case ST_int32: { int int_value = (int)floor(real_value + 0.5); - _int_range.validate(int_value, pack_error); - do_pack_int32(pack_data.get_write_pointer(4), int_value, pack_error); + _int_range.validate(int_value, range_error); + do_pack_int32(pack_data.get_write_pointer(4), int_value); } break; case ST_int64: { PN_int64 int64_value = (PN_int64)floor(real_value + 0.5); - _int64_range.validate(int64_value, pack_error); - do_pack_int64(pack_data.get_write_pointer(8), int64_value, pack_error); + _int64_range.validate(int64_value, range_error); + do_pack_int64(pack_data.get_write_pointer(8), int64_value); } break; case ST_uint8: { unsigned int int_value = (unsigned int)floor(real_value + 0.5); - _uint_range.validate(int_value, pack_error); - do_pack_uint8(pack_data.get_write_pointer(1), int_value, pack_error); + _uint_range.validate(int_value, range_error); + validate_uint_limits(int_value, 8, range_error); + do_pack_uint8(pack_data.get_write_pointer(1), int_value); } break; case ST_uint16: { unsigned int int_value = (unsigned int)floor(real_value + 0.5); - _uint_range.validate(int_value, pack_error); - do_pack_uint16(pack_data.get_write_pointer(2), int_value, pack_error); + _uint_range.validate(int_value, range_error); + validate_uint_limits(int_value, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), int_value); } break; case ST_uint32: { unsigned int int_value = (unsigned int)floor(real_value + 0.5); - _uint_range.validate(int_value, pack_error); - do_pack_uint32(pack_data.get_write_pointer(4), int_value, pack_error); + _uint_range.validate(int_value, range_error); + do_pack_uint32(pack_data.get_write_pointer(4), int_value); } break; case ST_uint64: { PN_uint64 int64_value = (PN_uint64)floor(real_value + 0.5); - _uint64_range.validate(int64_value, pack_error); - do_pack_uint64(pack_data.get_write_pointer(8), int64_value, pack_error); + _uint64_range.validate(int64_value, range_error); + do_pack_uint64(pack_data.get_write_pointer(8), int64_value); } break; case ST_float64: - _double_range.validate(real_value, pack_error); - do_pack_float64(pack_data.get_write_pointer(8), real_value, pack_error); + _double_range.validate(real_value, range_error); + do_pack_float64(pack_data.get_write_pointer(8), real_value); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::pack_int // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_int(DCPackData &pack_data, int value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_int(DCPackData &pack_data, int value, + bool &pack_error, bool &range_error) const { int int_value = value * _divisor; switch (_type) { case ST_int8: - _int_range.validate(int_value, pack_error); - do_pack_int8(pack_data.get_write_pointer(1), int_value, pack_error); + _int_range.validate(int_value, range_error); + validate_int_limits(int_value, 8, range_error); + do_pack_int8(pack_data.get_write_pointer(1), int_value); break; case ST_int16: - _int_range.validate(int_value, pack_error); - do_pack_int16(pack_data.get_write_pointer(2), int_value, pack_error); + _int_range.validate(int_value, range_error); + validate_int_limits(int_value, 16, range_error); + do_pack_int16(pack_data.get_write_pointer(2), int_value); break; case ST_int32: - _int_range.validate(int_value, pack_error); - do_pack_int32(pack_data.get_write_pointer(4), int_value, pack_error); + _int_range.validate(int_value, range_error); + do_pack_int32(pack_data.get_write_pointer(4), int_value); break; case ST_int64: - _int64_range.validate(int_value, pack_error); - do_pack_int64(pack_data.get_write_pointer(8), int_value, pack_error); + _int64_range.validate(int_value, range_error); + do_pack_int64(pack_data.get_write_pointer(8), int_value); break; case ST_uint8: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + validate_uint_limits((unsigned int)int_value, 8, range_error); + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value); break; case ST_uint16: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + validate_uint_limits((unsigned int)int_value, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value); break; case ST_uint32: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value); break; case ST_uint64: - _uint64_range.validate((unsigned int)int_value, pack_error); - do_pack_uint64(pack_data.get_write_pointer(8), (unsigned int)int_value, pack_error); + _uint64_range.validate((unsigned int)int_value, range_error); + do_pack_uint64(pack_data.get_write_pointer(8), (unsigned int)int_value); break; case ST_float64: - _double_range.validate(int_value, pack_error); - do_pack_float64(pack_data.get_write_pointer(8), int_value, pack_error); + _double_range.validate(int_value, range_error); + do_pack_float64(pack_data.get_write_pointer(8), int_value); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::pack_uint // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_uint(DCPackData &pack_data, unsigned int value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_uint(DCPackData &pack_data, unsigned int value, + bool &pack_error, bool &range_error) const { unsigned int int_value = value * _divisor; switch (_type) { case ST_int8: - _int_range.validate((int)int_value, pack_error); - do_pack_int8(pack_data.get_write_pointer(1), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + validate_int_limits((int)int_value, 8, range_error); + do_pack_int8(pack_data.get_write_pointer(1), (int)int_value); break; case ST_int16: - _int_range.validate((int)int_value, pack_error); - do_pack_int16(pack_data.get_write_pointer(2), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + validate_int_limits((int)int_value, 16, range_error); + do_pack_int16(pack_data.get_write_pointer(2), (int)int_value); break; case ST_int32: - _int_range.validate((int)int_value, pack_error); - do_pack_int32(pack_data.get_write_pointer(4), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + do_pack_int32(pack_data.get_write_pointer(4), (int)int_value); break; case ST_int64: - _int64_range.validate((int)int_value, pack_error); - do_pack_int64(pack_data.get_write_pointer(8), (int)int_value, pack_error); + _int64_range.validate((int)int_value, range_error); + do_pack_int64(pack_data.get_write_pointer(8), (int)int_value); break; case ST_uint8: - _uint_range.validate(int_value, pack_error); - do_pack_uint8(pack_data.get_write_pointer(1), int_value, pack_error); + _uint_range.validate(int_value, range_error); + validate_uint_limits(int_value, 8, range_error); + do_pack_uint8(pack_data.get_write_pointer(1), int_value); break; case ST_uint16: - _uint_range.validate(int_value, pack_error); - do_pack_uint16(pack_data.get_write_pointer(2), int_value, pack_error); + _uint_range.validate(int_value, range_error); + validate_uint_limits(int_value, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), int_value); break; case ST_uint32: - _uint_range.validate(int_value, pack_error); - do_pack_uint32(pack_data.get_write_pointer(4), int_value, pack_error); + _uint_range.validate(int_value, range_error); + do_pack_uint32(pack_data.get_write_pointer(4), int_value); break; case ST_uint64: - _uint64_range.validate(int_value, pack_error); - do_pack_uint64(pack_data.get_write_pointer(8), int_value, pack_error); + _uint64_range.validate(int_value, range_error); + do_pack_uint64(pack_data.get_write_pointer(8), int_value); break; case ST_float64: - _double_range.validate(int_value, pack_error); - do_pack_float64(pack_data.get_write_pointer(8), int_value, pack_error); + _double_range.validate(int_value, range_error); + do_pack_float64(pack_data.get_write_pointer(8), int_value); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::pack_int64 // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_int64(DCPackData &pack_data, PN_int64 value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_int64(DCPackData &pack_data, PN_int64 value, + bool &pack_error, bool &range_error) const { PN_int64 int_value = value * _divisor; switch (_type) { case ST_int8: - _int_range.validate((int)int_value, pack_error); - do_pack_int8(pack_data.get_write_pointer(1), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + validate_int64_limits(int_value, 8, range_error); + do_pack_int8(pack_data.get_write_pointer(1), (int)int_value); break; case ST_int16: - _int_range.validate((int)int_value, pack_error); - do_pack_int16(pack_data.get_write_pointer(2), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + validate_int64_limits(int_value, 16, range_error); + do_pack_int16(pack_data.get_write_pointer(2), (int)int_value); break; case ST_int32: - _int_range.validate((int)int_value, pack_error); - do_pack_int32(pack_data.get_write_pointer(4), (int)int_value, pack_error); + _int_range.validate((int)int_value, range_error); + validate_int64_limits(int_value, 32, range_error); + do_pack_int32(pack_data.get_write_pointer(4), (int)int_value); break; case ST_int64: - _int64_range.validate(int_value, pack_error); - do_pack_int64(pack_data.get_write_pointer(8), int_value, pack_error); + _int64_range.validate(int_value, range_error); + do_pack_int64(pack_data.get_write_pointer(8), int_value); break; case ST_uint8: - _uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error); - do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)(PN_uint64)int_value, pack_error); + _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error); + validate_uint64_limits((PN_uint64)int_value, 8, range_error); + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)(PN_uint64)int_value); break; case ST_uint16: - _uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error); - do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)(PN_uint64)int_value, pack_error); + _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error); + validate_uint64_limits((PN_uint64)int_value, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)(PN_uint64)int_value); break; case ST_uint32: - _uint_range.validate((unsigned int)(PN_uint64)int_value, pack_error); - do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)(PN_uint64)int_value, pack_error); + _uint_range.validate((unsigned int)(PN_uint64)int_value, range_error); + validate_uint64_limits((PN_uint64)int_value, 32, range_error); + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)(PN_uint64)int_value); break; case ST_uint64: - _uint64_range.validate((PN_uint64)int_value, pack_error); - do_pack_uint64(pack_data.get_write_pointer(8), (PN_uint64)int_value, pack_error); + _uint64_range.validate((PN_uint64)int_value, range_error); + do_pack_uint64(pack_data.get_write_pointer(8), (PN_uint64)int_value); break; case ST_float64: - _double_range.validate((double)int_value, pack_error); - do_pack_float64(pack_data.get_write_pointer(8), (double)int_value, pack_error); + _double_range.validate((double)int_value, range_error); + do_pack_float64(pack_data.get_write_pointer(8), (double)int_value); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::pack_uint64 // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_uint64(DCPackData &pack_data, PN_uint64 value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_uint64(DCPackData &pack_data, PN_uint64 value, + bool &pack_error, bool &range_error) const { PN_uint64 int_value = value * _divisor; switch (_type) { case ST_int8: - _int_range.validate((int)(PN_int64)int_value, pack_error); - do_pack_int8(pack_data.get_write_pointer(1), (int)(PN_int64)int_value, pack_error); + _int_range.validate((int)(PN_int64)int_value, range_error); + validate_int64_limits((PN_int64)int_value, 8, range_error); + do_pack_int8(pack_data.get_write_pointer(1), (int)(PN_int64)int_value); break; case ST_int16: - _int_range.validate((int)(PN_int64)int_value, pack_error); - do_pack_int16(pack_data.get_write_pointer(2), (int)(PN_int64)int_value, pack_error); + _int_range.validate((int)(PN_int64)int_value, range_error); + validate_int64_limits((PN_int64)int_value, 16, range_error); + do_pack_int16(pack_data.get_write_pointer(2), (int)(PN_int64)int_value); break; case ST_int32: - _int_range.validate((int)(PN_int64)int_value, pack_error); - do_pack_int32(pack_data.get_write_pointer(4), (int)(PN_int64)int_value, pack_error); + _int_range.validate((int)(PN_int64)int_value, range_error); + validate_int64_limits((PN_int64)int_value, 32, range_error); + do_pack_int32(pack_data.get_write_pointer(4), (int)(PN_int64)int_value); break; case ST_int64: - _int64_range.validate((PN_int64)int_value, pack_error); - do_pack_int64(pack_data.get_write_pointer(8), (PN_int64)int_value, pack_error); + _int64_range.validate((PN_int64)int_value, range_error); + do_pack_int64(pack_data.get_write_pointer(8), (PN_int64)int_value); break; case ST_uint8: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + validate_uint64_limits(int_value, 8, range_error); + do_pack_uint8(pack_data.get_write_pointer(1), (unsigned int)int_value); break; case ST_uint16: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + validate_uint64_limits(int_value, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), (unsigned int)int_value); break; case ST_uint32: - _uint_range.validate((unsigned int)int_value, pack_error); - do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value, pack_error); + _uint_range.validate((unsigned int)int_value, range_error); + validate_uint64_limits(int_value, 32, range_error); + do_pack_uint32(pack_data.get_write_pointer(4), (unsigned int)int_value); break; case ST_uint64: - _uint64_range.validate(int_value, pack_error); - do_pack_uint64(pack_data.get_write_pointer(8), int_value, pack_error); + _uint64_range.validate(int_value, range_error); + do_pack_uint64(pack_data.get_write_pointer(8), int_value); break; case ST_float64: - _double_range.validate((double)int_value, pack_error); - do_pack_float64(pack_data.get_write_pointer(8), (double)int_value, pack_error); + _double_range.validate((double)int_value, range_error); + do_pack_float64(pack_data.get_write_pointer(8), (double)int_value); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::pack_string // Access: Published, Virtual // Description: Packs the indicated numeric or string value into the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -pack_string(DCPackData &pack_data, const string &value) const { - bool pack_error = false; +void DCSimpleParameter:: +pack_string(DCPackData &pack_data, const string &value, + bool &pack_error, bool &range_error) const { size_t string_length = value.length(); - _uint_range.validate(string_length, pack_error); + _uint_range.validate(string_length, range_error); switch (_type) { case ST_string: case ST_blob: - do_pack_uint16(pack_data.get_write_pointer(2), string_length, - pack_error); + validate_uint_limits(string_length, 16, range_error); + do_pack_uint16(pack_data.get_write_pointer(2), string_length); pack_data.append_data(value.data(), string_length); break; case ST_blob32: - do_pack_uint32(pack_data.get_write_pointer(4), string_length, - pack_error); + do_pack_uint32(pack_data.get_write_pointer(4), string_length); pack_data.append_data(value.data(), string_length); break; default: - return false; + pack_error = true; } - - return !pack_error; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_double // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_double(const char *data, size_t length, size_t &p, double &value) const { +void DCSimpleParameter:: +unpack_double(const char *data, size_t length, size_t &p, double &value, + bool &pack_error, bool &range_error) const { switch (_type) { case ST_int8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int8(data + p); + _int_range.validate(int_value, range_error); + value = int_value; + p++; } - value = do_unpack_int8(data + p); - p++; break; case ST_int16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int16(data + p); + _int_range.validate(int_value, range_error); + value = int_value; + p += 2; } - value = do_unpack_int16(data + p); - p += 2; break; case ST_int32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int32(data + p); + _int_range.validate(int_value, range_error); + value = int_value; + p += 4; } - value = do_unpack_int32(data + p); - p += 4; break; case ST_int64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_int64 int_value = do_unpack_int64(data + p); + _int64_range.validate(int_value, range_error); + value = (double)int_value; + p += 8; } - value = (double)do_unpack_int64(data + p); - p += 8; break; case ST_uint8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint8(data + p); + _uint_range.validate(uint_value, range_error); + value = uint_value; + p++; } - value = do_unpack_uint8(data + p); - p++; break; case ST_uint16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint16(data + p); + _uint_range.validate(uint_value, range_error); + value = uint_value; + p += 2; } - value = do_unpack_uint16(data + p); - p += 2; break; case ST_uint32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint32(data + p); + _uint_range.validate(uint_value, range_error); + value = uint_value; + p += 4; } - value = do_unpack_uint32(data + p); - p += 4; break; case ST_uint64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_uint64 uint_value = do_unpack_uint64(data + p); + _uint64_range.validate(uint_value, range_error); + value = (double)uint_value; + p += 8; } - value = (double)do_unpack_uint64(data + p); - p += 8; break; case ST_float64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + value = do_unpack_float64(data + p); + _double_range.validate(value, range_error); + p += 8; } - value = do_unpack_float64(data + p); - p += 8; break; default: - return false; + pack_error = true; + return; } if (_divisor != 1) { value = value / _divisor; } - return true; + return; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_int // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_int(const char *data, size_t length, size_t &p, int &value) const { +void DCSimpleParameter:: +unpack_int(const char *data, size_t length, size_t &p, int &value, + bool &pack_error, bool &range_error) const { switch (_type) { case ST_int8: if (p + 1 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int8(data + p); + _int_range.validate(value, range_error); p++; break; case ST_int16: if (p + 2 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int16(data + p); + _int_range.validate(value, range_error); p += 2; break; case ST_int32: if (p + 4 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int32(data + p); + _int_range.validate(value, range_error); p += 4; break; case ST_int64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_int64 int_value = do_unpack_uint64(data + p); + _int64_range.validate(int_value, range_error); + value = (int)int_value; + p += 8; } - value = (int)do_unpack_int64(data + p); - p += 8; break; case ST_uint8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint8(data + p); + _uint_range.validate(uint_value, range_error); + value = uint_value; + p++; } - value = (int)do_unpack_uint8(data + p); - p++; break; case ST_uint16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint16(data + p); + _uint_range.validate(uint_value, range_error); + value = (int)uint_value; + p += 2; } - value = (int)do_unpack_uint16(data + p); - p += 2; break; case ST_uint32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint32(data + p); + _uint_range.validate(uint_value, range_error); + value = (int)uint_value; + p += 4; } - value = (int)do_unpack_uint32(data + p); - p += 4; break; case ST_uint64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_uint64 uint_value = do_unpack_uint64(data + p); + _uint64_range.validate(uint_value, range_error); + value = (int)(unsigned int)uint_value; + p += 8; } - value = (int)(unsigned int)do_unpack_uint64(data + p); - p += 8; break; case ST_float64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + double real_value = do_unpack_float64(data + p); + _double_range.validate(real_value, range_error); + value = (int)real_value; + p += 8; } - value = (int)do_unpack_float64(data + p); - p += 8; break; default: - return false; + pack_error = true; + return; } if (_divisor != 1) { value = value / _divisor; } - return true; + return; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_uint // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const { +void DCSimpleParameter:: +unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value, + bool &pack_error, bool &range_error) const { switch (_type) { case ST_int8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int8(data + p); + _int_range.validate(int_value, range_error); + value = (unsigned int)int_value; + p++; } - value = (unsigned int)do_unpack_int8(data + p); - p++; break; case ST_int16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int16(data + p); + _int_range.validate(int_value, range_error); + value = (unsigned int)int_value; + p += 2; } - value = (unsigned int)do_unpack_int16(data + p); - p += 2; break; case ST_int32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int32(data + p); + _int_range.validate(int_value, range_error); + value = (unsigned int)int_value; + p += 4; } - value = (unsigned int)do_unpack_int32(data + p); - p += 4; break; case ST_int64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_int64 int_value = do_unpack_int64(data + p); + _int64_range.validate(int_value, range_error); + value = (unsigned int)(int)int_value; + p += 8; } - value = (unsigned int)do_unpack_int64(data + p); - p += 8; break; case ST_uint8: if (p + 1 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint8(data + p); + _uint_range.validate(value, range_error); p++; break; case ST_uint16: if (p + 2 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint16(data + p); + _uint_range.validate(value, range_error); p += 2; break; case ST_uint32: if (p + 4 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint32(data + p); + _uint_range.validate(value, range_error); p += 4; break; case ST_uint64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_uint64 uint_value = do_unpack_uint64(data + p); + _uint64_range.validate(uint_value, range_error); + value = (unsigned int)uint_value; + p += 8; } - value = (unsigned int)do_unpack_uint64(data + p); - p += 8; break; case ST_float64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + double real_value = do_unpack_float64(data + p); + _double_range.validate(real_value, range_error); + value = (unsigned int)real_value; + p += 8; } - value = (unsigned int)do_unpack_float64(data + p); - p += 8; break; default: - return false; + pack_error = true; + return; } if (_divisor != 1) { value = value / _divisor; } - return true; + return; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_int64 // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const { +void DCSimpleParameter:: +unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value, + bool &pack_error, bool &range_error) const { switch (_type) { case ST_int8: if (p + 1 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int8(data + p); + _int_range.validate(value, range_error); p++; break; case ST_int16: if (p + 2 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int16(data + p); + _int_range.validate(value, range_error); p += 2; break; case ST_int32: if (p + 4 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int32(data + p); + _int_range.validate(value, range_error); p += 4; break; case ST_int64: if (p + 8 > length) { - return false; + pack_error = true; + return; } value = do_unpack_int64(data + p); + _int64_range.validate(value, range_error); p += 8; break; case ST_uint8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint8(data + p); + _uint_range.validate(uint_value, range_error); + value = (PN_int64)(int)uint_value; + p++; } - value = (int)do_unpack_uint8(data + p); - p++; break; case ST_uint16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint16(data + p); + _uint_range.validate(uint_value, range_error); + value = (PN_int64)(int)uint_value; + p += 2; } - value = (int)do_unpack_uint16(data + p); - p += 2; break; case ST_uint32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + unsigned int uint_value = do_unpack_uint32(data + p); + _uint_range.validate(uint_value, range_error); + value = (PN_int64)(int)uint_value; + p += 4; } - value = (int)do_unpack_uint32(data + p); - p += 4; break; case ST_uint64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_uint64 uint_value = do_unpack_uint64(data + p); + _uint64_range.validate(uint_value, range_error); + value = (PN_int64)uint_value; + p += 8; } - value = (PN_int64)do_unpack_uint64(data + p); - p += 8; break; case ST_float64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + double real_value = do_unpack_float64(data + p); + _double_range.validate(real_value, range_error); + value = (PN_int64)real_value; + p += 8; } - value = (PN_int64)do_unpack_float64(data + p); - p += 8; break; default: - return false; + pack_error = true; + return; } if (_divisor != 1) { value = value / _divisor; } - return true; + return; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_uint64 // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const { +void DCSimpleParameter:: +unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value, + bool &pack_error, bool &range_error) const { switch (_type) { case ST_int8: - if (p + 1 > length) { - return false; + { + if (p + 1 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int8(data + p); + _int_range.validate(int_value, range_error); + value = (PN_uint64)(unsigned int)int_value; + p++; } - value = (unsigned int)do_unpack_int8(data + p); - p++; break; case ST_int16: - if (p + 2 > length) { - return false; + { + if (p + 2 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int16(data + p); + _int_range.validate(int_value, range_error); + value = (PN_uint64)(unsigned int)int_value; + p += 2; } - value = (unsigned int)do_unpack_int16(data + p); - p += 2; break; case ST_int32: - if (p + 4 > length) { - return false; + { + if (p + 4 > length) { + pack_error = true; + return; + } + int int_value = do_unpack_int32(data + p); + _int_range.validate(int_value, range_error); + value = (PN_uint64)(unsigned int)int_value; + p += 4; } - value = (unsigned int)do_unpack_int32(data + p); - p += 4; break; case ST_int64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + PN_int64 int_value = do_unpack_int64(data + p); + _int64_range.validate(int_value, range_error); + value = (PN_uint64)int_value; + p += 8; } - value = (PN_uint64)do_unpack_int64(data + p); - p += 8; break; case ST_uint8: if (p + 1 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint8(data + p); + _uint_range.validate(value, range_error); p++; break; case ST_uint16: if (p + 2 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint16(data + p); + _uint_range.validate(value, range_error); p += 2; break; case ST_uint32: if (p + 4 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint32(data + p); + _uint_range.validate(value, range_error); p += 4; break; case ST_uint64: if (p + 8 > length) { - return false; + pack_error = true; + return; } value = do_unpack_uint64(data + p); + _uint64_range.validate(value, range_error); p += 8; break; case ST_float64: - if (p + 8 > length) { - return false; + { + if (p + 8 > length) { + pack_error = true; + return; + } + double real_value = do_unpack_float64(data + p); + _double_range.validate(real_value, range_error); + value = (PN_uint64)real_value; + p += 8; } - value = (PN_uint64)do_unpack_float64(data + p); - p += 8; break; default: - return false; + pack_error = true; + return; } if (_divisor != 1) { value = value / _divisor; } - return true; + return; } //////////////////////////////////////////////////////////////////// // Function: DCSimpleParameter::unpack_string // Access: Public, Virtual // Description: Unpacks the current numeric or string value from the -// stream. Returns true on success, false on failure. +// stream. //////////////////////////////////////////////////////////////////// -bool DCSimpleParameter:: -unpack_string(const char *data, size_t length, size_t &p, string &value) const { +void DCSimpleParameter:: +unpack_string(const char *data, size_t length, size_t &p, string &value, + bool &pack_error, bool &range_error) const { size_t string_length; switch (_type) { case ST_string: case ST_blob: if (p + 2 > length) { - return false; + pack_error = true; + return; } string_length = do_unpack_uint16(data + p); p += 2; @@ -1242,22 +1501,179 @@ unpack_string(const char *data, size_t length, size_t &p, string &value) const { case ST_blob32: if (p + 4 > length) { - return false; + pack_error = true; + return; } string_length = do_unpack_uint32(data + p); p += 4; break; default: - return false; + pack_error = true; + return; } + _uint_range.validate(string_length, range_error); if (p + string_length > length) { - return false; + pack_error = true; + return; } value = string(data + p, string_length); p += string_length; + return; +} + +//////////////////////////////////////////////////////////////////// +// Function: DCSimpleParameter::unpack_validate +// Access: Public, Virtual +// Description: Internally unpacks the current numeric or string +// value and validates it against the type range limits, +// but does not return the value. Returns true on +// success, false on failure (e.g. we don't know how to +// validate this field). +//////////////////////////////////////////////////////////////////// +bool DCSimpleParameter:: +unpack_validate(const char *data, size_t length, size_t &p, + bool &pack_error, bool &range_error) const { + switch (_type) { + case ST_int8: + { + if (p + 1 > length) { + pack_error = true; + return true; + } + int int_value = do_unpack_int8(data + p); + _int_range.validate(int_value, range_error); + p++; + } + break; + + case ST_int16: + { + if (p + 2 > length) { + pack_error = true; + return true; + } + int int_value = do_unpack_int16(data + p); + _int_range.validate(int_value, range_error); + p += 2; + } + break; + + case ST_int32: + { + if (p + 4 > length) { + pack_error = true; + return true; + } + int int_value = do_unpack_int32(data + p); + _int_range.validate(int_value, range_error); + p += 4; + } + break; + + case ST_int64: + { + if (p + 8 > length) { + pack_error = true; + return true; + } + PN_int64 int_value = do_unpack_int64(data + p); + _int64_range.validate(int_value, range_error); + p += 8; + } + break; + + case ST_uint8: + { + if (p + 1 > length) { + pack_error = true; + return true; + } + unsigned int uint_value = do_unpack_uint8(data + p); + _uint_range.validate(uint_value, range_error); + p++; + } + break; + + case ST_uint16: + { + if (p + 2 > length) { + pack_error = true; + return true; + } + unsigned int uint_value = do_unpack_uint16(data + p); + _uint_range.validate(uint_value, range_error); + p += 2; + } + break; + + case ST_uint32: + { + if (p + 4 > length) { + pack_error = true; + return true; + } + unsigned int uint_value = do_unpack_uint32(data + p); + _uint_range.validate(uint_value, range_error); + p += 4; + } + break; + + case ST_uint64: + { + if (p + 8 > length) { + pack_error = true; + return true; + } + PN_uint64 uint_value = do_unpack_uint64(data + p); + _uint64_range.validate(uint_value, range_error); + p += 8; + } + break; + + case ST_float64: + { + if (p + 8 > length) { + pack_error = true; + return true; + } + double real_value = do_unpack_float64(data + p); + _double_range.validate(real_value, range_error); + p += 8; + } + break; + + case ST_string: + case ST_blob: + { + if (p + 2 > length) { + pack_error = true; + return true; + } + size_t string_length = do_unpack_uint16(data + p); + _uint_range.validate(string_length, range_error); + p += 2 + string_length; + } + break; + + case ST_blob32: + { + if (p + 4 > length) { + pack_error = true; + return true; + } + size_t string_length = do_unpack_uint32(data + p); + _uint_range.validate(string_length, range_error); + p += 4 + string_length; + } + break; + + default: + return false; + } + return true; } @@ -1265,8 +1681,9 @@ unpack_string(const char *data, size_t length, size_t &p, string &value) const { // Function: DCSimpleParameter::unpack_skip // Access: Public, Virtual // Description: Increments p to the end of the current field without -// actually unpacking any data. Returns true on -// success, false on failure. +// actually unpacking any data or performing any range +// validation. Returns true on success, false on +// failure (e.g. we don't know how to skip this field). //////////////////////////////////////////////////////////////////// bool DCSimpleParameter:: unpack_skip(const char *data, size_t length, size_t &p) const { @@ -1408,6 +1825,12 @@ generate_hash(HashGenerator &hashgen) const { hashgen.add_int(_type); hashgen.add_int(_divisor); + + _int_range.generate_hash(hashgen); + _int64_range.generate_hash(hashgen); + _uint_range.generate_hash(hashgen); + _uint64_range.generate_hash(hashgen); + _double_range.generate_hash(hashgen); } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/dcparser/dcSimpleParameter.h b/direct/src/dcparser/dcSimpleParameter.h index a84bedac89..86bd35cc50 100644 --- a/direct/src/dcparser/dcSimpleParameter.h +++ b/direct/src/dcparser/dcSimpleParameter.h @@ -48,29 +48,43 @@ PUBLISHED: public: bool set_divisor(int divisor); - void set_range(const DCDoubleRange &range); + bool set_range(const DCDoubleRange &range); virtual int calc_num_nested_fields(size_t length_bytes) const; virtual DCPackerInterface *get_nested_field(int n) const; - virtual bool pack_double(DCPackData &pack_data, double value) const; - virtual bool pack_int(DCPackData &pack_data, int value) const; - virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; - virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; - virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; - virtual bool pack_string(DCPackData &pack_data, const string &value) const; + virtual void pack_double(DCPackData &pack_data, double value, + bool &pack_error, bool &range_error) const; + virtual void pack_int(DCPackData &pack_data, int value, + bool &pack_error, bool &range_error) const; + virtual void pack_uint(DCPackData &pack_data, unsigned int value, + bool &pack_error, bool &range_error) const; + virtual void pack_int64(DCPackData &pack_data, PN_int64 value, + bool &pack_error, bool &range_error) const; + virtual void pack_uint64(DCPackData &pack_data, PN_uint64 value, + bool &pack_error, bool &range_error) const; + virtual void pack_string(DCPackData &pack_data, const string &value, + bool &pack_error, bool &range_error) const; - virtual bool unpack_double(const char *data, size_t length, size_t &p, double &value) const; - virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; - virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; - virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; - virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; - virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; + virtual void unpack_double(const char *data, size_t length, size_t &p, + double &value, bool &pack_error, bool &range_error) const; + virtual void unpack_int(const char *data, size_t length, size_t &p, + int &value, bool &pack_error, bool &range_error) const; + virtual void unpack_uint(const char *data, size_t length, size_t &p, + unsigned int &value, bool &pack_error, bool &range_error) const; + virtual void unpack_int64(const char *data, size_t length, size_t &p, + PN_int64 &value, bool &pack_error, bool &range_error) const; + virtual void unpack_uint64(const char *data, size_t length, size_t &p, + PN_uint64 &value, bool &pack_error, bool &range_error) const; + virtual void unpack_string(const char *data, size_t length, size_t &p, + string &value, bool &pack_error, bool &range_error) const; + virtual bool unpack_validate(const char *data, size_t length, size_t &p, + bool &pack_error, bool &range_error) const; virtual bool unpack_skip(const char *data, size_t length, size_t &p) const; virtual void output_instance(ostream &out, const string &prename, const string &name, const string &postname) const; - virtual void generate_hash(HashGenerator &hash) const; + virtual void generate_hash(HashGenerator &hashgen) const; private: static DCSimpleParameter *create_nested_field(DCSubatomicType type, int divisor);