Browse Source

[2497] Fix HINFO parsing in the string parser

The lexer variant also uses the string parser eventually (for now).
Mukund Sivaraman 12 years ago
parent
commit
1a2787f32f

+ 18 - 6
src/lib/dns/rdata/generic/hinfo_13.cc

@@ -39,11 +39,22 @@ using namespace isc::dns::characterstr;
 
 HINFO::HINFO(const std::string& hinfo_str) {
     string::const_iterator input_iterator = hinfo_str.begin();
-    cpu_ = getNextCharacterString(hinfo_str, input_iterator);
 
-    skipLeftSpaces(hinfo_str, input_iterator);
+    bool quoted;
+    cpu_ = getNextCharacterString(hinfo_str, input_iterator, &quoted);
+
+    skipLeftSpaces(hinfo_str, input_iterator, quoted);
 
     os_ = getNextCharacterString(hinfo_str, input_iterator);
+
+    // Skip whitespace at the end.
+    while (input_iterator < hinfo_str.end() && isspace(*input_iterator)) {
+        ++input_iterator;
+    }
+    if (input_iterator < hinfo_str.end()) {
+        isc_throw(InvalidRdataText,
+                  "Invalid HINFO text format: too many fields.");
+    }
 }
 
 HINFO::HINFO(InputBuffer& buffer, size_t rdata_len) {
@@ -108,16 +119,17 @@ HINFO::getOS() const {
 
 void
 HINFO::skipLeftSpaces(const std::string& input_str,
-                      std::string::const_iterator& input_iterator)
+                      std::string::const_iterator& input_iterator,
+                      bool optional)
 {
     if (input_iterator >= input_str.end()) {
         isc_throw(InvalidRdataText,
-                  "Invalid HINFO text format, field is missing.");
+                  "Invalid HINFO text format: field is missing.");
     }
 
-    if (!isspace(*input_iterator)) {
+    if (!isspace(*input_iterator) && !optional) {
         isc_throw(InvalidRdataText,
-            "Invalid HINFO text format, fields are not separated by space.");
+            "Invalid HINFO text format: fields are not separated by space.");
     }
     // Skip white spaces
     while (input_iterator < input_str.end() && isspace(*input_iterator)) {

+ 8 - 1
src/lib/dns/rdata/generic/hinfo_13.h

@@ -46,10 +46,17 @@ public:
 private:
     /// Skip the left whitespaces of the input string
     ///
+    /// If \c optional argument is \c true and no spaces occur at the
+    /// current location, then nothing happens. If \c optional is
+    /// \c false and no spaces occur at the current location, then
+    /// the \c InvalidRdataText exception is thrown.
+    ///
     /// \param input_str The input string
     /// \param input_iterator From which the skipping started
+    /// \param optional If true, the spaces are optionally skipped.
     void skipLeftSpaces(const std::string& input_str,
-                        std::string::const_iterator& input_iterator);
+                        std::string::const_iterator& input_iterator,
+                        bool optional);
 
     /// Helper template function for toWire()
     ///

+ 13 - 4
src/lib/dns/tests/rdata_hinfo_unittest.cc

@@ -57,8 +57,11 @@ TEST_F(Rdata_HINFO_Test, createFromText) {
 }
 
 TEST_F(Rdata_HINFO_Test, badText) {
-    // Fields must be seperated by spaces
-    EXPECT_THROW(const HINFO hinfo("\"Pentium\"\"Linux\""), InvalidRdataText);
+    // Only 2 fields must exist
+    EXPECT_THROW(const HINFO hinfo("\"Pentium\"\"Linux\"\"Computer\""),
+                 InvalidRdataText);
+    EXPECT_THROW(const HINFO hinfo("\"Pentium\" \"Linux\" \"Computer\""),
+                 InvalidRdataText);
     // Field cannot be missing
     EXPECT_THROW(const HINFO hinfo("Pentium"), InvalidRdataText);
     // The <character-string> cannot exceed 255 characters
@@ -82,10 +85,16 @@ TEST_F(Rdata_HINFO_Test, createFromLexer) {
     EXPECT_EQ(0, rdata_hinfo.compare(
         *test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
                                      hinfo_str)));
-
+    EXPECT_EQ(0, rdata_hinfo.compare(
+        *test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
+                                     "\"Pentium\"\"Linux\"")));
     // Exceptions cause NULL to be returned.
     EXPECT_FALSE(test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
-                                             "\"Pentium\"\"Linux\""));
+                                             "\"Pentium\"\"Linux\""
+                                             "\"Computer\""));
+    EXPECT_FALSE(test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
+                                             "\"Pentium\" \"Linux\" "
+                                             "\"Computer\""));
 }
 
 TEST_F(Rdata_HINFO_Test, toText) {