Browse Source

[2086] Add basic checking of offsets data

Jelte Jansen 12 years ago
parent
commit
8b731b4250

+ 29 - 0
src/lib/dns/labelsequence.cc

@@ -23,6 +23,35 @@
 namespace isc {
 namespace dns {
 
+LabelSequence::LabelSequence(const uint8_t* data,
+                             const uint8_t* offsets,
+                             size_t offsets_size) : data_(data),
+                                                    offsets_(offsets),
+                                                    offsets_size_(offsets_size),
+                                                    first_label_(0),
+                                                    last_label_(offsets_size_)
+{
+    // Check offsets
+    if (data == NULL || offsets == NULL) {
+        isc_throw(BadValue, "Null pointer passed to LabelSequence constructor");
+    }
+    if (offsets_size == 0) {
+        isc_throw(BadValue, "Zero offsets to LabelSequence constructor");
+    }
+    if (offsets_size > Name::MAX_LABELS) {
+        isc_throw(BadValue, "MAX_LABELS exceeded");
+    }
+    for (size_t cur_offset = 0; cur_offset < offsets_size; ++cur_offset) {
+        if (offsets[cur_offset] > Name::MAX_LABELLEN) {
+            isc_throw(BadValue, "MAX_LABEL_LEN exceeded");
+        }
+        if (cur_offset > 0 && offsets[cur_offset] <= offsets[cur_offset - 1]) {
+            isc_throw(BadValue, "Offset smaller than previous offset");
+        }
+    }
+}
+
+
 const uint8_t*
 LabelSequence::getData(size_t *len) const {
     *len = getDataLength();

+ 1 - 6
src/lib/dns/labelsequence.h

@@ -76,12 +76,7 @@ public:
     /// \param offsets_size The size of the offsets data
     LabelSequence(const uint8_t* data,
                   const uint8_t* offsets,
-                  size_t offsets_size) : data_(data),
-                                         offsets_(offsets),
-                                         offsets_size_(offsets_size),
-                                         first_label_(0),
-                                         last_label_(offsets_size_)
-    {}
+                  size_t offsets_size);
 
     /// \brief Return the wire-format data for this LabelSequence
     ///

+ 25 - 0
src/lib/dns/tests/labelsequence_unittest.cc

@@ -724,4 +724,29 @@ TEST(LabelSequence, rawConstruction) {
     EXPECT_EQ(0, result.getCommonLabels());
 }
 
+// Test with some data that exceeds limits (MAX_LABELS and MAX_LABEL_LEN)
+TEST(LabelSequence, badRawConstruction) {
+    uint8_t data[1] = { 0 };
+    uint8_t offsets[1] = { 0 };
+
+    EXPECT_THROW(LabelSequence(NULL, offsets, 1), isc::BadValue);
+    EXPECT_THROW(LabelSequence(data, NULL, 1), isc::BadValue);
+    EXPECT_THROW(LabelSequence(data, offsets, 0), isc::BadValue);
+
+    // exceed MAX_LABELS
+    EXPECT_THROW(LabelSequence(data, offsets, 127), isc::BadValue);
+
+    // exceed MAX_LABEL_LEN
+    uint8_t offsets_toolonglabel[1] = { 64 };
+    EXPECT_THROW(LabelSequence(data, offsets_toolonglabel, 1), isc::BadValue);
+
+    // Add an offset that is lower than the previous offset
+    uint8_t offsets_lower[3] = { 0, 8, 4 };
+    EXPECT_THROW(LabelSequence(data, offsets_lower, 3), isc::BadValue);
+
+    // Add an offset that is equal to the previous offset
+    uint8_t offsets_noincrease[3] = { 0, 8, 8 };
+    EXPECT_THROW(LabelSequence(data, offsets_noincrease, 3), isc::BadValue);
+}
+
 }