Browse Source

[2571] Change from char to int when we need special character values.

In cases where we use values outside of normal character range (-128
to 127 or 0 to 255) to indicate special things, like EOF, we need to
insure that we can hold these values. To do that, we use an int.

It turns out that the default type conversions also meant that our
JSON conversion from strings would break in some cases. A test was
added to show that, and to confirm the fix.
Shane Kerr 12 years ago
parent
commit
6b6cbde6a1
3 changed files with 12 additions and 12 deletions
  1. 10 11
      src/lib/cc/data.cc
  2. 1 0
      src/lib/cc/tests/data_unittests.cc
  3. 1 1
      tests/tools/perfdhcp/command_options.cc

+ 10 - 11
src/lib/cc/data.cc

@@ -240,7 +240,7 @@ Element::createMap() {
 //
 //
 namespace {
 namespace {
 bool
 bool
-char_in(const char c, const char *chars) {
+char_in(const int c, const char *chars) {
     for (size_t i = 0; i < strlen(chars); ++i) {
     for (size_t i = 0; i < strlen(chars); ++i) {
         if (chars[i] == c) {
         if (chars[i] == c) {
             return (true);
             return (true);
@@ -251,7 +251,7 @@ char_in(const char c, const char *chars) {
 
 
 void
 void
 skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
 skip_chars(std::istream &in, const char *chars, int& line, int& pos) {
-    char c = in.peek();
+    int c = in.peek();
     while (char_in(c, chars) && c != EOF) {
     while (char_in(c, chars) && c != EOF) {
         if (c == '\n') {
         if (c == '\n') {
             ++line;
             ++line;
@@ -273,7 +273,7 @@ void
 skip_to(std::istream &in, const std::string& file, int& line,
 skip_to(std::istream &in, const std::string& file, int& line,
         int& pos, const char* chars, const char* may_skip="")
         int& pos, const char* chars, const char* may_skip="")
 {
 {
-    char c = in.get();
+    int c = in.get();
     ++pos;
     ++pos;
     while (c != EOF) {
     while (c != EOF) {
         if (c == '\n') {
         if (c == '\n') {
@@ -296,7 +296,7 @@ skip_to(std::istream &in, const std::string& file, int& line,
             --pos;
             --pos;
             return;
             return;
         } else {
         } else {
-            throwJSONError(std::string("'") + c + "' read, one of \"" + chars + "\" expected", file, line, pos);
+            throwJSONError(std::string("'") + std::string(1, c) + "' read, one of \"" + chars + "\" expected", file, line, pos);
         }
         }
     }
     }
     throwJSONError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
     throwJSONError(std::string("EOF read, one of \"") + chars + "\" expected", file, line, pos);
@@ -308,9 +308,8 @@ std::string
 str_from_stringstream(std::istream &in, const std::string& file, const int line,
 str_from_stringstream(std::istream &in, const std::string& file, const int line,
                       int& pos) throw (JSONError)
                       int& pos) throw (JSONError)
 {
 {
-    char c;
     std::stringstream ss;
     std::stringstream ss;
-    c = in.get();
+    int c = in.get();
     ++pos;
     ++pos;
     if (c == '"') {
     if (c == '"') {
         c = in.get();
         c = in.get();
@@ -354,7 +353,7 @@ str_from_stringstream(std::istream &in, const std::string& file, const int line,
             in.get();
             in.get();
             ++pos;
             ++pos;
         }
         }
-        ss << c;
+        ss.put(c);
         c = in.get();
         c = in.get();
         ++pos;
         ++pos;
     }
     }
@@ -461,7 +460,7 @@ ElementPtr
 from_stringstream_list(std::istream &in, const std::string& file, int& line,
 from_stringstream_list(std::istream &in, const std::string& file, int& line,
                        int& pos)
                        int& pos)
 {
 {
-    char c = 0;
+    int c = 0;
     ElementPtr list = Element::createList();
     ElementPtr list = Element::createList();
     ConstElementPtr cur_list_element;
     ConstElementPtr cur_list_element;
 
 
@@ -484,7 +483,7 @@ from_stringstream_map(std::istream &in, const std::string& file, int& line,
 {
 {
     ElementPtr map = Element::createMap();
     ElementPtr map = Element::createMap();
     skip_chars(in, WHITESPACE, line, pos);
     skip_chars(in, WHITESPACE, line, pos);
-    char c = in.peek();
+    int c = in.peek();
     if (c == EOF) {
     if (c == EOF) {
         throwJSONError(std::string("Unterminated map, <string> or } expected"), file, line, pos);
         throwJSONError(std::string("Unterminated map, <string> or } expected"), file, line, pos);
     } else if (c == '}') {
     } else if (c == '}') {
@@ -578,7 +577,7 @@ ElementPtr
 Element::fromJSON(std::istream &in, const std::string& file, int& line,
 Element::fromJSON(std::istream &in, const std::string& file, int& line,
                   int& pos) throw(JSONError)
                   int& pos) throw(JSONError)
 {
 {
-    char c = 0;
+    int c = 0;
     ElementPtr element;
     ElementPtr element;
     bool el_read = false;
     bool el_read = false;
     skip_chars(in, WHITESPACE, line, pos);
     skip_chars(in, WHITESPACE, line, pos);
@@ -633,7 +632,7 @@ Element::fromJSON(std::istream &in, const std::string& file, int& line,
             case EOF:
             case EOF:
                 break;
                 break;
             default:
             default:
-                throwJSONError(std::string("error: unexpected character ") + c, file, line, pos);
+                throwJSONError(std::string("error: unexpected character ") + std::string(1, c), file, line, pos);
                 break;
                 break;
         }
         }
     }
     }

+ 1 - 0
src/lib/cc/tests/data_unittests.cc

@@ -91,6 +91,7 @@ TEST(Element, from_and_to_json) {
     sv.push_back("-1");
     sv.push_back("-1");
     sv.push_back("-1.234");
     sv.push_back("-1.234");
     sv.push_back("-123.456");
     sv.push_back("-123.456");
+    sv.push_back("\"\xFF\"");
 
 
     BOOST_FOREACH(const std::string& s, sv) {
     BOOST_FOREACH(const std::string& s, sv) {
         // test << operator, which uses Element::str()
         // test << operator, which uses Element::str()

+ 1 - 1
tests/tools/perfdhcp/command_options.cc

@@ -134,7 +134,7 @@ CommandOptions::parse(int argc, char** const argv) {
 
 
 bool
 bool
 CommandOptions::initialize(int argc, char** argv) {
 CommandOptions::initialize(int argc, char** argv) {
-    char opt = 0;               // Subsequent options returned by getopt()
+    int opt = 0;                // Subsequent options returned by getopt()
     std::string drop_arg;       // Value of -D<value>argument
     std::string drop_arg;       // Value of -D<value>argument
     size_t percent_loc = 0;     // Location of % sign in -D<value>
     size_t percent_loc = 0;     // Location of % sign in -D<value>
     double drop_percent = 0;    // % value (1..100) in -D<value%>
     double drop_percent = 0;    // % value (1..100) in -D<value%>