[svn] commit: r774 - in /branches/jinmei-dnsrdata2/src/lib/dns/cpp: rdata.cc rdata.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Feb 10 03:48:36 UTC 2010
Author: jinmei
Date: Wed Feb 10 03:48:36 2010
New Revision: 774
Log:
bug fixes identified via unittests, some cleanups, added operator<<
Modified:
branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.cc
branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.h
Modified: branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.cc
==============================================================================
--- branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.cc (original)
+++ branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.cc Wed Feb 10 03:48:36 2010
@@ -19,6 +19,7 @@
#include <sstream>
#include <iomanip>
#include <ios>
+#include <ostream>
#include <vector>
#include <stdint.h>
@@ -55,6 +56,10 @@
createRdata(const RRType& rrtype, const RRClass& rrclass,
InputBuffer& buffer, size_t len)
{
+ if (len > MAX_RDLENGTH) {
+ dns_throw(InvalidRdataLength, "RDLENGTH too large");
+ }
+
size_t old_pos = buffer.getPosition();
RdataPtr rdata =
@@ -103,6 +108,10 @@
Generic::Generic(InputBuffer& buffer, size_t rdata_len)
{
+ if (rdata_len > MAX_RDLENGTH) {
+ dns_throw(InvalidRdataLength, "RDLENGTH too large");
+ }
+
vector<uint8_t> data(rdata_len);
buffer.readData(&data[0], rdata_len);
data.resize(rdata_len);
@@ -133,30 +142,35 @@
if (rdlen < 0 || rdlen > 0xffff) {
dns_throw(InvalidRdataLength, "RDATA length is out of range");
}
-
+ iss >> ws; // skip any white spaces
+
+ // Hexadecimal encoding of RDATA: each segment must consist of an even
+ // number of hex digits.
vector<uint8_t> data;
while (!iss.eof() && data.size() < rdlen) {
- string bytes;
- iss >> bytes;
- // Hexadecimal encoding of RDATA: each segment must consist of an even
- // number of hex digits.
- if ((iss.rdstate() & (ios::badbit | ios::failbit)) != 0 ||
- (bytes.size() % 2) != 0) {
+ // extract two characters, which should compose a single byte of data.
+ char buf[2];
+ iss.read(buf, sizeof(buf));
+ if ((iss.rdstate() & (ios::badbit | ios::failbit)) != 0) {
dns_throw(InvalidRdataText,
"Invalid hex encoding of generic RDATA");
}
- for (int pos = 0; pos < bytes.size(); pos += 2) {
- istringstream iss_hex(bytes.substr(pos, 2));
-
- unsigned int ch;
- iss_hex >> hex >> ch;
- if (iss_hex.rdstate() != ios::eofbit) {
- dns_throw(InvalidRdataText,
- "Invalid hex encoding of generic RDATA");
- }
- data.push_back(ch);
+ // convert it to a single byte integer as a hex digit.
+ istringstream iss_byte(string(buf, sizeof(buf)));
+ unsigned int ch;
+ iss_byte >> hex >> ch;
+ if (iss_byte.rdstate() != ios::eofbit) {
+ dns_throw(InvalidRdataText,
+ "Invalid hex encoding of generic RDATA");
}
+ data.push_back(ch);
+ iss >> ws; // skip spaces
+ }
+
+ if (!iss.eof()) {
+ dns_throw(InvalidRdataLength,
+ "RDLENGTH is too small for generic RDATA");
}
if (data.size() != rdlen) {
@@ -178,7 +192,7 @@
return (*this);
}
- GenericImpl* newimpl = new GenericImpl(*impl_);
+ GenericImpl* newimpl = new GenericImpl(*source.impl_);
delete impl_;
impl_ = newimpl;
@@ -223,17 +237,16 @@
renderer.writeData(&impl_->data_[0], impl_->data_.size());
}
-int
-Generic::compare(const Rdata& other) const
-{
- const Generic& other_rdata = dynamic_cast<const Generic&>(other);
-
- size_t this_len = impl_->data_.size();
- size_t other_len = other_rdata.impl_->data_.size();
+namespace {
+inline int
+compare_internal(const GenericImpl& lhs, const GenericImpl& rhs)
+{
+ size_t this_len = lhs.data_.size();
+ size_t other_len = rhs.data_.size();
size_t len = (this_len < other_len) ? this_len : other_len;
int cmp;
- if ((cmp = memcmp(&impl_->data_[0], &other_rdata.impl_->data_[0], len))
+ if ((cmp = memcmp(&lhs.data_[0], &rhs.data_[0], len))
!= 0) {
return (cmp);
} else {
@@ -241,7 +254,21 @@
(this_len < other_len) ? -1 : 1);
}
}
-
+}
+
+int
+Generic::compare(const Rdata& other) const
+{
+ const Generic& other_rdata = dynamic_cast<const Generic&>(other);
+
+ return (compare_internal(*impl_, *other_rdata.impl_));
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Generic& rdata)
+{
+ return (os << rdata.toText());
+}
} // end of namespace generic
} // end of namespace rdata
Modified: branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.h
==============================================================================
--- branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.h (original)
+++ branches/jinmei-dnsrdata2/src/lib/dns/cpp/rdata.h Wed Feb 10 03:48:36 2010
@@ -66,6 +66,10 @@
class Rdata;
typedef boost::shared_ptr<Rdata> RdataPtr;
+/// \brief Possible maximum length of RDATA, which is the maximum unsigned
+/// 16 bit value.
+const size_t MAX_RDLENGTH = 65535;
+
/// Abstract RDATA class
class Rdata {
protected:
@@ -106,14 +110,6 @@
/// be more polymorphic, but might involve significant overhead, especially
/// for a large size of RDATA.
virtual int compare(const Rdata& other) const = 0;
-
- // not yet:
- // methods specific derived classes: throw an exception by default
- //virtual Address& getAddress() = 0;
- //virtual Name& getName() = 0;
-
- // polymorphic copy constructor (XXX should revisit it)
- //virtual Rdata* copy() const = 0;
};
namespace generic {
@@ -123,7 +119,7 @@
public:
explicit Generic(const std::string& rdata_string);
explicit Generic(InputBuffer& buffer, size_t rdata_len);
- explicit Generic(const Generic& source);
+ Generic(const Generic& source);
Generic& operator=(const Generic& source);
virtual std::string toText() const;
virtual void toWire(OutputBuffer& buffer) const;
@@ -137,6 +133,9 @@
private:
GenericImpl* impl_;
};
+
+std::ostream&
+operator<<(std::ostream& os, const Generic& rdata);
} // end of namespace "generic"
///
More information about the bind10-changes
mailing list