From: Christian Hofstaedtler Date: Tue, 18 Mar 2014 13:55:46 +0000 (+0100) Subject: API: fix escaping in zone ids X-Git-Tag: rec-3.6.0-rc1~122^2^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F1335%2Fhead;p=thirdparty%2Fpdns.git API: fix escaping in zone ids Realized that we should have been taking the character code as hex, so it actually fits into two digits. --- diff --git a/pdns/ws-api.cc b/pdns/ws-api.cc index c6c062facc..759bb39e1c 100644 --- a/pdns/ws-api.cc +++ b/pdns/ws-api.cc @@ -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; } diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 7995f0a724..23c8f81000 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -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)