more range checking

This commit is contained in:
David Rose 2004-06-22 15:23:05 +00:00
parent b0b2fe350c
commit 414ec1b386
21 changed files with 1214 additions and 554 deletions

View File

@ -49,7 +49,7 @@ public:
virtual void output_instance(ostream &out, const string &prename, virtual void output_instance(ostream &out, const string &prename,
const string &name, const string &postname) const; const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hash) const; virtual void generate_hash(HashGenerator &hashgen) const;
private: private:
DCParameter *_element_type; DCParameter *_element_type;

View File

@ -64,7 +64,7 @@ PUBLISHED:
public: public:
DCAtomicField(const string &name); DCAtomicField(const string &name);
virtual void write(ostream &out, bool brief, int indent_level) const; 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; virtual DCPackerInterface *get_nested_field(int n) const;

View File

@ -86,7 +86,7 @@ public:
~DCClass(); ~DCClass();
virtual void write(ostream &out, bool brief, int indent_level) const; 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_field(DCField *field);
bool add_parameter(DCParameter *parameter); bool add_parameter(DCParameter *parameter);

View File

@ -47,7 +47,7 @@ public:
virtual void output_instance(ostream &out, const string &prename, virtual void output_instance(ostream &out, const string &prename,
const string &name, const string &postname) const; const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hash) const; virtual void generate_hash(HashGenerator &hashgen) const;
private: private:
DCClass *_dclass; DCClass *_dclass;

View File

@ -100,6 +100,26 @@ parse_string(const string &formatted_string) {
return packer.get_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 #ifdef HAVE_PYTHON
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCField::pack_args // Function: DCField::pack_args
@ -130,8 +150,13 @@ pack_args(Datagram &datagram, PyObject *sequence) const {
PyObject *str = PyObject_Str(tuple); PyObject *str = PyObject_Str(tuple);
ostringstream strm; ostringstream strm;
strm << "Incorrect arguments or value out of range on field: " << get_name() if (packer.had_pack_error()) {
<< PyString_AsString(str); 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(str);
Py_DECREF(tuple); Py_DECREF(tuple);
@ -172,7 +197,14 @@ unpack_args(DatagramIterator &iterator) const {
} }
ostringstream strm; 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()); nassert_raise(strm.str());
return object; return object;

View File

@ -52,6 +52,8 @@ PUBLISHED:
string format_data(const string &packed_data); string format_data(const string &packed_data);
string parse_string(const string &formatted_string); string parse_string(const string &formatted_string);
bool validate_ranges(const string &packed_data) const;
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
bool pack_args(Datagram &datagram, PyObject *sequence) const; bool pack_args(Datagram &datagram, PyObject *sequence) const;
PyObject *unpack_args(DatagramIterator &iterator) const; PyObject *unpack_args(DatagramIterator &iterator) const;
@ -66,7 +68,7 @@ public:
DCField(const string &name); DCField(const string &name);
virtual ~DCField(); virtual ~DCField();
virtual void write(ostream &out, bool brief, int indent_level) const=0; 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); void set_number(int number);

View File

@ -66,7 +66,7 @@ PUBLISHED:
unsigned long get_hash() const; unsigned long get_hash() const;
public: public:
void generate_hash(HashGenerator &hash) const; void generate_hash(HashGenerator &hashgen) const;
bool add_class(DCClass *dclass); bool add_class(DCClass *dclass);
void add_import_module(const string &import_module); void add_import_module(const string &import_module);
void add_import_symbol(const string &import_symbol); void add_import_symbol(const string &import_symbol);

View File

@ -44,7 +44,7 @@ public:
void add_atomic(DCAtomicField *atomic); void add_atomic(DCAtomicField *atomic);
virtual void write(ostream &out, bool brief, int indent_level) const; 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; virtual DCPackerInterface *get_nested_field(int n) const;

View File

@ -27,6 +27,17 @@ INLINE DCNumericRange<NUM>::
DCNumericRange() { DCNumericRange() {
} }
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
INLINE DCNumericRange<NUM>::
DCNumericRange(Number min, Number max) {
add_range(min, max);
}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::Copy Constructor // Function: DCNumericRange::Copy Constructor
// Access: Public // Access: Public
@ -89,6 +100,26 @@ validate(Number num, bool &validation_error) const {
} }
} }
////////////////////////////////////////////////////////////////////
// Function: DCNumericRange::generate_hash
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template <class NUM>
void DCNumericRange<NUM>::
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 // Function: DCNumericRange::output
// Access: Public // Access: Public

View File

@ -20,6 +20,7 @@
#define DCNUMERICRANGE_H #define DCNUMERICRANGE_H
#include "dcbase.h" #include "dcbase.h"
#include "hashGenerator.h"
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Class : DCNumericRange // Class : DCNumericRange
@ -33,12 +34,15 @@ public:
typedef NUM Number; typedef NUM Number;
INLINE DCNumericRange(); INLINE DCNumericRange();
INLINE DCNumericRange(Number min, Number max);
INLINE DCNumericRange(const DCNumericRange &copy); INLINE DCNumericRange(const DCNumericRange &copy);
INLINE void operator = (const DCNumericRange &copy); INLINE void operator = (const DCNumericRange &copy);
bool is_in_range(Number num) const; bool is_in_range(Number num) const;
INLINE void validate(Number num, bool &validation_error) const; INLINE void validate(Number num, bool &validation_error) const;
void generate_hash(HashGenerator &hashgen) const;
void output(ostream &out, Number divisor = 1) const; void output(ostream &out, Number divisor = 1) const;
public: public:

View File

@ -110,9 +110,7 @@ pack_double(double value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_double(_pack_data, value)) { _current_field->pack_double(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -129,9 +127,7 @@ pack_int(int value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_int(_pack_data, value)) { _current_field->pack_int(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -148,9 +144,7 @@ pack_uint(unsigned int value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_uint(_pack_data, value)) { _current_field->pack_uint(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -167,9 +161,7 @@ pack_int64(PN_int64 value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_int64(_pack_data, value)) { _current_field->pack_int64(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -186,9 +178,7 @@ pack_uint64(PN_uint64 value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_uint64(_pack_data, value)) { _current_field->pack_uint64(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -205,9 +195,7 @@ pack_string(const string &value) {
if (_current_field == NULL) { if (_current_field == NULL) {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->pack_string(_pack_data, value)) { _current_field->pack_string(_pack_data, value, _pack_error, _range_error);
_pack_error = true;
}
advance(); advance();
} }
} }
@ -244,9 +232,8 @@ unpack_double() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -267,9 +254,8 @@ unpack_int() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -290,9 +276,8 @@ unpack_uint() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -313,9 +298,8 @@ unpack_int64() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -336,9 +320,8 @@ unpack_uint64() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -359,9 +342,8 @@ unpack_string() {
_pack_error = true; _pack_error = true;
} else { } else {
if (!_current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p, value)) { _current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p,
_pack_error = true; value, _pack_error, _range_error);
}
advance(); advance();
} }
@ -386,16 +368,41 @@ unpack_literal_value() {
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPacker::had_pack_error // Function: DCPacker::had_pack_error
// Access: Published // Access: Published
// Description: Returns true if there has been an error in packing // Description: Returns true if there has been an packing error
// since the most recent call to begin(). It is // since the most recent call to begin(); in particular,
// most useful to call this after end() to validate // this may be called after end() has returned false to
// the entire packing run. // 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:: INLINE bool DCPacker::
had_pack_error() const { had_pack_error() const {
return _pack_error; 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 // Function: DCPacker::get_num_unpacked_bytes
// Access: Published // Access: Published

View File

@ -40,6 +40,7 @@ DCPacker() {
_current_field_index = 0; _current_field_index = 0;
_num_nested_fields = 0; _num_nested_fields = 0;
_pack_error = false; _pack_error = false;
_range_error = false;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -65,6 +66,7 @@ begin_pack(const DCPackerInterface *root) {
_mode = M_pack; _mode = M_pack;
_pack_error = false; _pack_error = false;
_range_error = false;
_pack_data.clear(); _pack_data.clear();
_root = root; _root = root;
@ -97,7 +99,7 @@ end_pack() {
clear(); clear();
return !_pack_error; return !_pack_error && !_range_error;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -128,6 +130,7 @@ begin_unpack(const char *data, size_t length,
_mode = M_unpack; _mode = M_unpack;
_pack_error = false; _pack_error = false;
_range_error = false;
set_unpack_data(data, length, false); set_unpack_data(data, length, false);
_unpack_p = 0; _unpack_p = 0;
@ -170,7 +173,7 @@ end_unpack() {
clear(); clear();
return !_pack_error; return !_pack_error && !_range_error;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -208,6 +211,7 @@ begin_repack(const char *data, size_t length,
_mode = M_repack; _mode = M_repack;
_pack_error = false; _pack_error = false;
_range_error = false;
set_unpack_data(data, length, false); set_unpack_data(data, length, false);
_unpack_p = 0; _unpack_p = 0;
@ -244,7 +248,7 @@ end_repack() {
_mode = M_idle; _mode = M_idle;
clear(); clear();
return !_pack_error; return !_pack_error && !_range_error;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -429,7 +433,6 @@ push() {
} else { } else {
_current_field = _current_parent->get_nested_field(_current_field_index); _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; size_t length = _pack_data.get_length() - _push_marker - length_bytes;
if (length_bytes == 4) { if (length_bytes == 4) {
DCPackerInterface::do_pack_uint32 DCPackerInterface::do_pack_uint32
(_pack_data.get_rewrite_pointer(_push_marker, 4), length, (_pack_data.get_rewrite_pointer(_push_marker, 4), length);
_pack_error);
} else { } else {
DCPackerInterface::validate_uint_limits(length, 16, _range_error);
DCPackerInterface::do_pack_uint16 DCPackerInterface::do_pack_uint16
(_pack_data.get_rewrite_pointer(_push_marker, 2), length, (_pack_data.get_rewrite_pointer(_push_marker, 2), length);
_pack_error);
} }
} }
} }
@ -488,13 +490,44 @@ pop() {
advance(); 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 // Function: DCPacker::unpack_skip
// Access: Published // Access: Published
// Description: Skips the current field without unpacking it and // 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() { unpack_skip() {
nassertv(_mode == M_unpack); nassertv(_mode == M_unpack);
if (_current_field == NULL) { if (_current_field == NULL) {

View File

@ -80,6 +80,7 @@ PUBLISHED:
INLINE PN_uint64 unpack_uint64(); INLINE PN_uint64 unpack_uint64();
INLINE string unpack_string(); INLINE string unpack_string();
INLINE string unpack_literal_value(); INLINE string unpack_literal_value();
INLINE void unpack_validate();
void unpack_skip(); void unpack_skip();
#ifdef HAVE_PYTHON #ifdef HAVE_PYTHON
@ -93,6 +94,7 @@ PUBLISHED:
void unpack_and_format(ostream &out); void unpack_and_format(ostream &out);
INLINE bool had_pack_error() const; INLINE bool had_pack_error() const;
INLINE bool had_range_error() const;
INLINE size_t get_num_unpacked_bytes() const; INLINE size_t get_num_unpacked_bytes() const;
INLINE string get_string() const; INLINE string get_string() const;
@ -147,6 +149,7 @@ private:
int _num_nested_fields; int _num_nested_fields;
bool _pack_error; bool _pack_error;
bool _range_error;
}; };
#include "dcPacker.I" #include "dcPacker.I"

View File

@ -117,11 +117,8 @@ get_pack_type() const {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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); 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: INLINE void DCPackerInterface::
do_pack_int32(char *buffer, int value, bool &) { do_pack_int32(char *buffer, int value) {
buffer[0] = (char)(value & 0xff); buffer[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 0xff); buffer[1] = (char)((value >> 8) & 0xff);
buffer[2] = (char)((value >> 16) & 0xff); buffer[2] = (char)((value >> 16) & 0xff);
@ -157,7 +151,7 @@ do_pack_int32(char *buffer, int value, bool &) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 0xff); buffer[1] = (char)((value >> 8) & 0xff);
buffer[2] = (char)((value >> 16) & 0xff); buffer[2] = (char)((value >> 16) & 0xff);
@ -174,11 +168,8 @@ do_pack_int64(char *buffer, PN_int64 value, bool &) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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); 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 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: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 0xff); buffer[1] = (char)((value >> 8) & 0xff);
buffer[2] = (char)((value >> 16) & 0xff); buffer[2] = (char)((value >> 16) & 0xff);
@ -214,7 +202,7 @@ do_pack_uint32(char *buffer, unsigned int value, bool &) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: 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[0] = (char)(value & 0xff);
buffer[1] = (char)((value >> 8) & 0xff); buffer[1] = (char)((value >> 8) & 0xff);
buffer[2] = (char)((value >> 16) & 0xff); buffer[2] = (char)((value >> 16) & 0xff);
@ -231,7 +219,7 @@ do_pack_uint64(char *buffer, PN_uint64 value, bool &) {
// Description: // Description:
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
INLINE void DCPackerInterface:: INLINE void DCPackerInterface::
do_pack_float64(char *buffer, double value, bool &) { do_pack_float64(char *buffer, double value) {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
// Reverse the byte ordering for big-endian machines. // Reverse the byte ordering for big-endian machines.
char *p = (char *)value; char *p = (char *)value;
@ -365,3 +353,76 @@ do_unpack_float64(const char *buffer) {
return *(double *)buffer; return *(double *)buffer;
#endif // WORDS_BIGENDIAN #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;
}
}

View File

@ -99,131 +99,145 @@ get_nested_field(int n) const {
// Function: DCPackerInterface::pack_double // Function: DCPackerInterface::pack_double
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_double(DCPackData &, double) const { pack_double(DCPackData &, double, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::pack_int // Function: DCPackerInterface::pack_int
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_int(DCPackData &, int) const { pack_int(DCPackData &, int, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::pack_uint // Function: DCPackerInterface::pack_uint
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_uint(DCPackData &, unsigned int) const { pack_uint(DCPackData &, unsigned int, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::pack_int64 // Function: DCPackerInterface::pack_int64
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_int64(DCPackData &, PN_int64) const { pack_int64(DCPackData &, PN_int64, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::pack_uint64 // Function: DCPackerInterface::pack_uint64
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_uint64(DCPackData &, PN_uint64) const { pack_uint64(DCPackData &, PN_uint64, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::pack_string // Function: DCPackerInterface::pack_string
// Access: Public, Virtual // Access: Public, Virtual
// Description: Packs the indicated numeric or string value into the // Description: Packs the indicated numeric or string value into the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
pack_string(DCPackData &, const string &) const { pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_double // Function: DCPackerInterface::unpack_double
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // Description: Unpacks the current numeric or string value from the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
unpack_double(const char *, size_t, size_t &, double &) const { unpack_double(const char *, size_t, size_t &, double &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_int // Function: DCPackerInterface::unpack_int
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // Description: Unpacks the current numeric or string value from the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
unpack_int(const char *, size_t, size_t &, int &) const { unpack_int(const char *, size_t, size_t &, int &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_uint // Function: DCPackerInterface::unpack_uint
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // Description: Unpacks the current numeric or string value from the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
unpack_uint(const char *, size_t, size_t &, unsigned int &) const { unpack_uint(const char *, size_t, size_t &, unsigned int &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_int64 // Function: DCPackerInterface::unpack_int64
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // Description: Unpacks the current numeric or string value from the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
unpack_int64(const char *, size_t, size_t &, PN_int64 &) const { unpack_int64(const char *, size_t, size_t &, PN_int64 &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_uint64 // Function: DCPackerInterface::unpack_uint64
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // Description: Unpacks the current numeric or string value from the
// stream. Returns true on success, false on failure. // stream.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: void DCPackerInterface::
unpack_uint64(const char *, size_t, size_t &, PN_uint64 &) const { unpack_uint64(const char *, size_t, size_t &, PN_uint64 &, bool &pack_error, bool &) const {
return false; pack_error = true;
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Function: DCPackerInterface::unpack_string // Function: DCPackerInterface::unpack_string
// Access: Public, Virtual // Access: Public, Virtual
// Description: Unpacks the current numeric or string value from the // 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:: 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; return false;
} }
@ -231,8 +245,9 @@ unpack_string(const char *, size_t, size_t &, string &) const {
// Function: DCPackerInterface::unpack_skip // Function: DCPackerInterface::unpack_skip
// Access: Public, Virtual // Access: Public, Virtual
// Description: Increments p to the end of the current field without // Description: Increments p to the end of the current field without
// actually unpacking any data. Returns true on // actually unpacking any data or performing any range
// success, false on failure. // validation. Returns true on success, false on
// failure (e.g. we don't know how to skip this field).
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool DCPackerInterface:: bool DCPackerInterface::
unpack_skip(const char *, size_t, size_t &) const { unpack_skip(const char *, size_t, size_t &) const {

View File

@ -83,33 +83,47 @@ public:
INLINE DCPackType get_pack_type() const; INLINE DCPackType get_pack_type() const;
virtual bool pack_double(DCPackData &pack_data, double value) const; virtual void pack_double(DCPackData &pack_data, double value,
virtual bool pack_int(DCPackData &pack_data, int value) const; bool &pack_error, bool &range_error) const;
virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; virtual void pack_int(DCPackData &pack_data, int value,
virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; bool &pack_error, bool &range_error) const;
virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; virtual void pack_uint(DCPackData &pack_data, unsigned int value,
virtual bool pack_string(DCPackData &pack_data, const string &value) const; 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 void unpack_double(const char *data, size_t length, size_t &p,
virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; double &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; virtual void unpack_int(const char *data, size_t length, size_t &p,
virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; int &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; virtual void unpack_uint(const char *data, size_t length, size_t &p,
virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; 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 bool unpack_skip(const char *data, size_t length, size_t &p) const;
// These are the low-level interfaces for packing and unpacking // These are the low-level interfaces for packing and unpacking
// numbers from a buffer. You're responsible for making sure the // numbers from a buffer. You're responsible for making sure the
// buffer has enough room, and for incrementing the pointer. // 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_int8(char *buffer, int value);
INLINE static void do_pack_int16(char *buffer, int value, bool &pack_error); INLINE static void do_pack_int16(char *buffer, int value);
INLINE static void do_pack_int32(char *buffer, int value, bool &pack_error); INLINE static void do_pack_int32(char *buffer, int value);
INLINE static void do_pack_int64(char *buffer, PN_int64 value, bool &pack_error); INLINE static void do_pack_int64(char *buffer, PN_int64 value);
INLINE static void do_pack_uint8(char *buffer, unsigned int value, bool &pack_error); INLINE static void do_pack_uint8(char *buffer, unsigned int value);
INLINE static void do_pack_uint16(char *buffer, unsigned int value, bool &pack_error); INLINE static void do_pack_uint16(char *buffer, unsigned int value);
INLINE static void do_pack_uint32(char *buffer, unsigned int value, bool &pack_error); INLINE static void do_pack_uint32(char *buffer, unsigned int value);
INLINE static void do_pack_uint64(char *buffer, PN_uint64 value, bool &pack_error); INLINE static void do_pack_uint64(char *buffer, PN_uint64 value);
INLINE static void do_pack_float64(char *buffer, double value, bool &pack_error); INLINE static void do_pack_float64(char *buffer, double value);
INLINE static int do_unpack_int8(const char *buffer); INLINE static int do_unpack_int8(const char *buffer);
INLINE static int do_unpack_int16(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 PN_uint64 do_unpack_uint64(const char *buffer);
INLINE static double do_unpack_float64(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; const DCPackerCatalog *get_catalog() const;
protected: protected:

View File

@ -65,7 +65,7 @@ public:
const string &name, const string &postname) const=0; const string &name, const string &postname) const=0;
void output_typedef_name(ostream &out, const string &prename, void output_typedef_name(ostream &out, const string &prename,
const string &name, const string &postname) const; const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hash) const; virtual void generate_hash(HashGenerator &hashgen) const;
private: private:
const DCTypedef *_typedef; const DCTypedef *_typedef;

View File

@ -224,14 +224,14 @@ static const short yyrline[] =
207, 209, 215, 220, 226, 242, 244, 247, 254, 262, 207, 209, 215, 220, 226, 242, 244, 247, 254, 262,
264, 265, 266, 267, 271, 279, 279, 290, 306, 308, 264, 265, 266, 267, 271, 279, 279, 290, 306, 308,
311, 313, 316, 322, 322, 346, 346, 357, 361, 363, 311, 313, 316, 322, 322, 346, 346, 357, 361, 363,
366, 371, 377, 388, 400, 412, 433, 438, 445, 452, 366, 371, 379, 390, 404, 418, 439, 444, 451, 458,
462, 468, 474, 485, 487, 491, 497, 503, 517, 521, 468, 474, 480, 491, 493, 497, 503, 509, 523, 527,
527, 532, 535, 540, 544, 548, 552, 552, 560, 560, 533, 538, 541, 546, 550, 554, 558, 558, 566, 566,
568, 568, 576, 582, 588, 596, 598, 601, 603, 606, 574, 574, 582, 588, 594, 602, 604, 607, 609, 612,
608, 611, 616, 620, 624, 628, 632, 636, 640, 644, 614, 617, 622, 626, 630, 634, 638, 642, 646, 650,
648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 654, 658, 662, 666, 670, 674, 678, 682, 686, 690,
690, 692, 696, 700, 704, 708, 712, 716, 720, 724, 696, 698, 702, 706, 710, 714, 718, 722, 726, 730,
730, 730, 741, 748, 761 736, 736, 747, 754, 767
}; };
#endif #endif
@ -1321,12 +1321,14 @@ case 51:
#line 372 "dcParser.yxx" #line 372 "dcParser.yxx"
{ {
DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-3].u.subatomic); 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; yyval.u.parameter = simple_param;
} }
break; break;
case 52: case 52:
#line 378 "dcParser.yxx" #line 380 "dcParser.yxx"
{ {
DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-2].u.subatomic); DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-2].u.subatomic);
if (yyvsp[0].u.integer == 0) { if (yyvsp[0].u.integer == 0) {
@ -1339,7 +1341,7 @@ case 52:
} }
break; break;
case 53: case 53:
#line 389 "dcParser.yxx" #line 391 "dcParser.yxx"
{ {
DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic);
if (yyvsp[-3].u.integer == 0) { if (yyvsp[-3].u.integer == 0) {
@ -1348,12 +1350,14 @@ case 53:
} else if (!simple_param->set_divisor(yyvsp[-3].u.integer)) { } else if (!simple_param->set_divisor(yyvsp[-3].u.integer)) {
yyerror("A divisor is only valid on a numeric type."); 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; yyval.u.parameter = simple_param;
} }
break; break;
case 54: case 54:
#line 401 "dcParser.yxx" #line 405 "dcParser.yxx"
{ {
DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic); DCSimpleParameter *simple_param = new DCSimpleParameter(yyvsp[-5].u.subatomic);
if (yyvsp[0].u.integer == 0) { if (yyvsp[0].u.integer == 0) {
@ -1362,12 +1366,14 @@ case 54:
} else if (!simple_param->set_divisor(yyvsp[0].u.integer)) { } else if (!simple_param->set_divisor(yyvsp[0].u.integer)) {
yyerror("A divisor is only valid on a numeric type."); 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; yyval.u.parameter = simple_param;
} }
break; break;
case 55: case 55:
#line 413 "dcParser.yxx" #line 419 "dcParser.yxx"
{ {
DCTypedef *dtypedef = dc_file->get_typedef_by_name(yyvsp[0].str); DCTypedef *dtypedef = dc_file->get_typedef_by_name(yyvsp[0].str);
if (dtypedef == (DCTypedef *)NULL) { if (dtypedef == (DCTypedef *)NULL) {
@ -1388,13 +1394,13 @@ case 55:
} }
break; break;
case 56: case 56:
#line 435 "dcParser.yxx" #line 441 "dcParser.yxx"
{ {
double_range.clear(); double_range.clear();
} }
break; break;
case 57: case 57:
#line 439 "dcParser.yxx" #line 445 "dcParser.yxx"
{ {
double_range.clear(); double_range.clear();
if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) {
@ -1403,7 +1409,7 @@ case 57:
} }
break; break;
case 58: case 58:
#line 446 "dcParser.yxx" #line 452 "dcParser.yxx"
{ {
double_range.clear(); double_range.clear();
if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) {
@ -1412,7 +1418,7 @@ case 58:
} }
break; break;
case 59: case 59:
#line 453 "dcParser.yxx" #line 459 "dcParser.yxx"
{ {
double_range.clear(); double_range.clear();
if (yyvsp[0].u.real >= 0) { if (yyvsp[0].u.real >= 0) {
@ -1424,7 +1430,7 @@ case 59:
} }
break; break;
case 60: case 60:
#line 463 "dcParser.yxx" #line 469 "dcParser.yxx"
{ {
if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) { if (!double_range.add_range(yyvsp[0].u.real, yyvsp[0].u.real)) {
yyerror("Overlapping range"); yyerror("Overlapping range");
@ -1432,7 +1438,7 @@ case 60:
} }
break; break;
case 61: case 61:
#line 469 "dcParser.yxx" #line 475 "dcParser.yxx"
{ {
if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) { if (!double_range.add_range(yyvsp[-2].u.real, yyvsp[0].u.real)) {
yyerror("Overlapping range"); yyerror("Overlapping range");
@ -1440,7 +1446,7 @@ case 61:
} }
break; break;
case 62: case 62:
#line 475 "dcParser.yxx" #line 481 "dcParser.yxx"
{ {
if (yyvsp[0].u.real >= 0) { if (yyvsp[0].u.real >= 0) {
yyerror("Syntax error"); yyerror("Syntax error");
@ -1451,26 +1457,26 @@ case 62:
} }
break; break;
case 64: case 64:
#line 488 "dcParser.yxx" #line 494 "dcParser.yxx"
{ {
yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter);
} }
break; break;
case 65: case 65:
#line 492 "dcParser.yxx" #line 498 "dcParser.yxx"
{ {
yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer);
} }
break; break;
case 66: case 66:
#line 499 "dcParser.yxx" #line 505 "dcParser.yxx"
{ {
current_parameter->set_name(yyvsp[0].str); current_parameter->set_name(yyvsp[0].str);
yyval.u.parameter = current_parameter; yyval.u.parameter = current_parameter;
} }
break; break;
case 67: case 67:
#line 504 "dcParser.yxx" #line 510 "dcParser.yxx"
{ {
if (yyvsp[0].u.integer == 0) { if (yyvsp[0].u.integer == 0) {
yyerror("Invalid divisor."); yyerror("Invalid divisor.");
@ -1486,85 +1492,85 @@ case 67:
} }
break; break;
case 68: case 68:
#line 518 "dcParser.yxx" #line 524 "dcParser.yxx"
{ {
yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter); yyval.u.parameter = new DCArrayParameter(yyvsp[-2].u.parameter);
} }
break; break;
case 69: case 69:
#line 522 "dcParser.yxx" #line 528 "dcParser.yxx"
{ {
yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer); yyval.u.parameter = new DCArrayParameter(yyvsp[-3].u.parameter, yyvsp[-1].u.integer);
} }
break; break;
case 70: case 70:
#line 529 "dcParser.yxx" #line 535 "dcParser.yxx"
{ {
yyval.u.real = (double)yyvsp[0].u.integer; yyval.u.real = (double)yyvsp[0].u.integer;
} }
break; break;
case 72: case 72:
#line 537 "dcParser.yxx" #line 543 "dcParser.yxx"
{ {
current_packer->pack_int64(yyvsp[0].u.integer); current_packer->pack_int64(yyvsp[0].u.integer);
} }
break; break;
case 73: case 73:
#line 541 "dcParser.yxx" #line 547 "dcParser.yxx"
{ {
current_packer->pack_double(yyvsp[0].u.real); current_packer->pack_double(yyvsp[0].u.real);
} }
break; break;
case 74: case 74:
#line 545 "dcParser.yxx" #line 551 "dcParser.yxx"
{ {
current_packer->pack_string(yyvsp[0].str); current_packer->pack_string(yyvsp[0].str);
} }
break; break;
case 75: case 75:
#line 549 "dcParser.yxx" #line 555 "dcParser.yxx"
{ {
current_packer->pack_literal_value(yyvsp[0].str); current_packer->pack_literal_value(yyvsp[0].str);
} }
break; break;
case 76: case 76:
#line 553 "dcParser.yxx" #line 559 "dcParser.yxx"
{ {
current_packer->push(); current_packer->push();
} }
break; break;
case 77: case 77:
#line 557 "dcParser.yxx" #line 563 "dcParser.yxx"
{ {
current_packer->pop(); current_packer->pop();
} }
break; break;
case 78: case 78:
#line 561 "dcParser.yxx" #line 567 "dcParser.yxx"
{ {
current_packer->push(); current_packer->push();
} }
break; break;
case 79: case 79:
#line 565 "dcParser.yxx" #line 571 "dcParser.yxx"
{ {
current_packer->pop(); current_packer->pop();
} }
break; break;
case 80: case 80:
#line 569 "dcParser.yxx" #line 575 "dcParser.yxx"
{ {
current_packer->push(); current_packer->push();
} }
break; break;
case 81: case 81:
#line 573 "dcParser.yxx" #line 579 "dcParser.yxx"
{ {
current_packer->pop(); current_packer->pop();
} }
break; break;
case 82: case 82:
#line 577 "dcParser.yxx" #line 583 "dcParser.yxx"
{ {
for (int i = 0; i < yyvsp[0].u.integer; i++) { for (int i = 0; i < yyvsp[0].u.integer; i++) {
current_packer->pack_int64(yyvsp[-2].u.integer); current_packer->pack_int64(yyvsp[-2].u.integer);
@ -1572,7 +1578,7 @@ case 82:
} }
break; break;
case 83: case 83:
#line 583 "dcParser.yxx" #line 589 "dcParser.yxx"
{ {
for (int i = 0; i < yyvsp[0].u.integer; i++) { for (int i = 0; i < yyvsp[0].u.integer; i++) {
current_packer->pack_double(yyvsp[-2].u.real); current_packer->pack_double(yyvsp[-2].u.real);
@ -1580,7 +1586,7 @@ case 83:
} }
break; break;
case 84: case 84:
#line 589 "dcParser.yxx" #line 595 "dcParser.yxx"
{ {
for (int i = 0; i < yyvsp[0].u.integer; i++) { for (int i = 0; i < yyvsp[0].u.integer; i++) {
current_packer->pack_literal_value(yyvsp[-2].str); current_packer->pack_literal_value(yyvsp[-2].str);
@ -1588,175 +1594,175 @@ case 84:
} }
break; break;
case 91: case 91:
#line 613 "dcParser.yxx" #line 619 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int8; yyval.u.subatomic = ST_int8;
} }
break; break;
case 92: case 92:
#line 617 "dcParser.yxx" #line 623 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int16; yyval.u.subatomic = ST_int16;
} }
break; break;
case 93: case 93:
#line 621 "dcParser.yxx" #line 627 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int32; yyval.u.subatomic = ST_int32;
} }
break; break;
case 94: case 94:
#line 625 "dcParser.yxx" #line 631 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int64; yyval.u.subatomic = ST_int64;
} }
break; break;
case 95: case 95:
#line 629 "dcParser.yxx" #line 635 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint8; yyval.u.subatomic = ST_uint8;
} }
break; break;
case 96: case 96:
#line 633 "dcParser.yxx" #line 639 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint16; yyval.u.subatomic = ST_uint16;
} }
break; break;
case 97: case 97:
#line 637 "dcParser.yxx" #line 643 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint32; yyval.u.subatomic = ST_uint32;
} }
break; break;
case 98: case 98:
#line 641 "dcParser.yxx" #line 647 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint64; yyval.u.subatomic = ST_uint64;
} }
break; break;
case 99: case 99:
#line 645 "dcParser.yxx" #line 651 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_float64; yyval.u.subatomic = ST_float64;
} }
break; break;
case 100: case 100:
#line 649 "dcParser.yxx" #line 655 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_string; yyval.u.subatomic = ST_string;
} }
break; break;
case 101: case 101:
#line 653 "dcParser.yxx" #line 659 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_blob; yyval.u.subatomic = ST_blob;
} }
break; break;
case 102: case 102:
#line 657 "dcParser.yxx" #line 663 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_blob32; yyval.u.subatomic = ST_blob32;
} }
break; break;
case 103: case 103:
#line 661 "dcParser.yxx" #line 667 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int8array; yyval.u.subatomic = ST_int8array;
} }
break; break;
case 104: case 104:
#line 665 "dcParser.yxx" #line 671 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int16array; yyval.u.subatomic = ST_int16array;
} }
break; break;
case 105: case 105:
#line 669 "dcParser.yxx" #line 675 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_int32array; yyval.u.subatomic = ST_int32array;
} }
break; break;
case 106: case 106:
#line 673 "dcParser.yxx" #line 679 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint8array; yyval.u.subatomic = ST_uint8array;
} }
break; break;
case 107: case 107:
#line 677 "dcParser.yxx" #line 683 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint16array; yyval.u.subatomic = ST_uint16array;
} }
break; break;
case 108: case 108:
#line 681 "dcParser.yxx" #line 687 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint32array; yyval.u.subatomic = ST_uint32array;
} }
break; break;
case 109: case 109:
#line 685 "dcParser.yxx" #line 691 "dcParser.yxx"
{ {
yyval.u.subatomic = ST_uint32uint8array; yyval.u.subatomic = ST_uint32uint8array;
} }
break; break;
case 111: case 111:
#line 693 "dcParser.yxx" #line 699 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_required); current_atomic->add_flag(DCAtomicField::F_required);
} }
break; break;
case 112: case 112:
#line 697 "dcParser.yxx" #line 703 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_broadcast); current_atomic->add_flag(DCAtomicField::F_broadcast);
} }
break; break;
case 113: case 113:
#line 701 "dcParser.yxx" #line 707 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_p2p); current_atomic->add_flag(DCAtomicField::F_p2p);
} }
break; break;
case 114: case 114:
#line 705 "dcParser.yxx" #line 711 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_ram); current_atomic->add_flag(DCAtomicField::F_ram);
} }
break; break;
case 115: case 115:
#line 709 "dcParser.yxx" #line 715 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_db); current_atomic->add_flag(DCAtomicField::F_db);
} }
break; break;
case 116: case 116:
#line 713 "dcParser.yxx" #line 719 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_clsend); current_atomic->add_flag(DCAtomicField::F_clsend);
} }
break; break;
case 117: case 117:
#line 717 "dcParser.yxx" #line 723 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_clrecv); current_atomic->add_flag(DCAtomicField::F_clrecv);
} }
break; break;
case 118: case 118:
#line 721 "dcParser.yxx" #line 727 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_ownsend); current_atomic->add_flag(DCAtomicField::F_ownsend);
} }
break; break;
case 119: case 119:
#line 725 "dcParser.yxx" #line 731 "dcParser.yxx"
{ {
current_atomic->add_flag(DCAtomicField::F_airecv); current_atomic->add_flag(DCAtomicField::F_airecv);
} }
break; break;
case 120: case 120:
#line 732 "dcParser.yxx" #line 738 "dcParser.yxx"
{ {
current_molecular = new DCMolecularField(yyvsp[-1].str); current_molecular = new DCMolecularField(yyvsp[-1].str);
if (!current_class->add_field(current_molecular)) { if (!current_class->add_field(current_molecular)) {
@ -1765,7 +1771,7 @@ case 120:
} }
break; break;
case 122: case 122:
#line 743 "dcParser.yxx" #line 749 "dcParser.yxx"
{ {
if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) {
current_molecular->add_atomic(yyvsp[0].u.atomic); current_molecular->add_atomic(yyvsp[0].u.atomic);
@ -1773,7 +1779,7 @@ case 122:
} }
break; break;
case 123: case 123:
#line 749 "dcParser.yxx" #line 755 "dcParser.yxx"
{ {
if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) { if (yyvsp[0].u.atomic != (DCAtomicField *)NULL) {
current_molecular->add_atomic(yyvsp[0].u.atomic); current_molecular->add_atomic(yyvsp[0].u.atomic);
@ -2018,4 +2024,4 @@ yyreturn:
#endif #endif
return yyresult; return yyresult;
} }
#line 764 "dcParser.yxx" #line 770 "dcParser.yxx"

View File

@ -371,7 +371,9 @@ type_name:
| type_token '(' double_range ')' | type_token '(' double_range ')'
{ {
DCSimpleParameter *simple_param = new DCSimpleParameter($1); 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; $$ = simple_param;
} }
| type_token '/' INTEGER | type_token '/' INTEGER
@ -394,7 +396,9 @@ type_name:
} else if (!simple_param->set_divisor($3)) { } else if (!simple_param->set_divisor($3)) {
yyerror("A divisor is only valid on a numeric type."); 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; $$ = simple_param;
} }
| type_token '(' double_range ')' '/' INTEGER | type_token '(' double_range ')' '/' INTEGER
@ -406,7 +410,9 @@ type_name:
} else if (!simple_param->set_divisor($6)) { } else if (!simple_param->set_divisor($6)) {
yyerror("A divisor is only valid on a numeric type."); 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; $$ = simple_param;
} }
| IDENTIFIER | IDENTIFIER

File diff suppressed because it is too large Load Diff

View File

@ -48,29 +48,43 @@ PUBLISHED:
public: public:
bool set_divisor(int divisor); 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 int calc_num_nested_fields(size_t length_bytes) const;
virtual DCPackerInterface *get_nested_field(int n) const; virtual DCPackerInterface *get_nested_field(int n) const;
virtual bool pack_double(DCPackData &pack_data, double value) const; virtual void pack_double(DCPackData &pack_data, double value,
virtual bool pack_int(DCPackData &pack_data, int value) const; bool &pack_error, bool &range_error) const;
virtual bool pack_uint(DCPackData &pack_data, unsigned int value) const; virtual void pack_int(DCPackData &pack_data, int value,
virtual bool pack_int64(DCPackData &pack_data, PN_int64 value) const; bool &pack_error, bool &range_error) const;
virtual bool pack_uint64(DCPackData &pack_data, PN_uint64 value) const; virtual void pack_uint(DCPackData &pack_data, unsigned int value,
virtual bool pack_string(DCPackData &pack_data, const string &value) const; 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 void unpack_double(const char *data, size_t length, size_t &p,
virtual bool unpack_int(const char *data, size_t length, size_t &p, int &value) const; double &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_uint(const char *data, size_t length, size_t &p, unsigned int &value) const; virtual void unpack_int(const char *data, size_t length, size_t &p,
virtual bool unpack_int64(const char *data, size_t length, size_t &p, PN_int64 &value) const; int &value, bool &pack_error, bool &range_error) const;
virtual bool unpack_uint64(const char *data, size_t length, size_t &p, PN_uint64 &value) const; virtual void unpack_uint(const char *data, size_t length, size_t &p,
virtual bool unpack_string(const char *data, size_t length, size_t &p, string &value) const; 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 bool unpack_skip(const char *data, size_t length, size_t &p) const;
virtual void output_instance(ostream &out, const string &prename, virtual void output_instance(ostream &out, const string &prename,
const string &name, const string &postname) const; const string &name, const string &postname) const;
virtual void generate_hash(HashGenerator &hash) const; virtual void generate_hash(HashGenerator &hashgen) const;
private: private:
static DCSimpleParameter *create_nested_field(DCSubatomicType type, int divisor); static DCSimpleParameter *create_nested_field(DCSubatomicType type, int divisor);