]> granicus.if.org Git - pdns/commitdiff
API: fix escaping in zone ids
authorChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 18 Mar 2014 13:55:46 +0000 (14:55 +0100)
committerChristian Hofstaedtler <christian@hofstaedtler.name>
Tue, 18 Mar 2014 13:57:52 +0000 (14:57 +0100)
Realized that we should have been taking the character code as hex,
so it actually fits into two digits.

pdns/ws-api.cc
regression-tests.api/test_Zones.py

index c6c062facc6c715d5fd9be616fabd33534c274b5..759bb39e1cb934dad843c688e3037f7dd10e8b90 100644 (file)
@@ -228,13 +228,27 @@ string apiZoneIdToName(const string& id) {
   std::size_t lastpos = 0, pos = 0;
   while ((pos = id.find('=', lastpos)) != string::npos) {
     ss << id.substr(lastpos, pos-lastpos);
-    if ((id[pos+1] >= '0' && id[pos+1] <= '9') &&
-        (id[pos+2] >= '0' && id[pos+2] <= '9')) {
-      char c = ((id[pos+1] - '0')*10) + (id[pos+2] - '0');
-      ss << c;
+    char c;
+    // decode tens
+    if (id[pos+1] >= '0' && id[pos+1] <= '9') {
+      c = id[pos+1] - '0';
+    } else if (id[pos+1] >= 'A' && id[pos+1] <= 'F') {
+      c = id[pos+1] - 'A' + 10;
     } else {
       throw HttpBadRequestException();
     }
+    c = c * 10;
+
+    // decode unit place
+    if (id[pos+2] >= '0' && id[pos+2] <= '9') {
+      c += id[pos+2] - '0';
+    } else if (id[pos+2] >= 'A' && id[pos+2] <= 'F') {
+      c += id[pos+2] - 'A' + 10;
+    } else {
+      throw HttpBadRequestException();
+    }
+
+    ss << c;
 
     lastpos = pos+3;
   }
@@ -261,7 +275,7 @@ string apiZoneNameToId(const string& name) {
         (*iter == '.') || (*iter == '-')) {
       ss << *iter;
     } else {
-      ss << "=" << std::setfill('0') << std::setw(2) << (int)(*iter);
+      ss << (boost::format("=%02X") % (int)(*iter));
     }
   }
 
@@ -275,7 +289,7 @@ string apiZoneNameToId(const string& name) {
   // special handling for the root zone, as a dot on it's own doesn't work
   // everywhere.
   if (id == ".") {
-    id = (boost::format("=%d") % (int)('.')).str();
+    id = (boost::format("=%02x") % (int)('.')).str();
   }
   return id;
 }
index 7995f0a724f466965fdc5721b701d461705f0cac..23c8f81000172645964bbd3fdb7a5b39efc289d4 100644 (file)
@@ -59,7 +59,7 @@ class AuthZones(ApiTestCase):
     def test_CreateZoneWithSymbols(self):
         payload, data = self.create_zone(name='foo/bar.'+unique_zone_name())
         name = payload['name']
-        expected_id = (name.replace('/', '=47')) + '.'
+        expected_id = (name.replace('/', '=2F')) + '.'
         for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
             self.assertIn(k, data)
             if k in payload:
@@ -69,7 +69,7 @@ class AuthZones(ApiTestCase):
     def test_GetZoneWithSymbols(self):
         payload, data = self.create_zone(name='foo/bar.'+unique_zone_name())
         name = payload['name']
-        zone_id = (name.replace('/', '=47')) + '.'
+        zone_id = (name.replace('/', '=2F')) + '.'
         r = self.session.get(self.url("/servers/localhost/zones/" + zone_id))
         for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'):
             self.assertIn(k, data)
@@ -591,7 +591,7 @@ class RecursorZones(ApiTestCase):
         data = r.json()
         # return values are normalized
         payload['name'] += '.'
-        expected_id = (payload['name'].replace('/', '=47'))
+        expected_id = (payload['name'].replace('/', '=2F'))
         for k in payload.keys():
             self.assertEquals(data[k], payload[k])
         self.assertEquals(data['id'], expected_id)