diff options
Diffstat (limited to 'net/dns/dns_util.cc')
-rw-r--r-- | net/dns/dns_util.cc | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/net/dns/dns_util.cc b/net/dns/dns_util.cc new file mode 100644 index 0000000..7ab60c6 --- /dev/null +++ b/net/dns/dns_util.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/dns/dns_util.h" + +#include <cstring> + +namespace net { + +// Based on DJB's public domain code. +bool DNSDomainFromDot(const base::StringPiece& dotted, std::string* out) { + const char* buf = dotted.data(); + unsigned n = dotted.size(); + char label[63]; + size_t labellen = 0; /* <= sizeof label */ + char name[255]; + size_t namelen = 0; /* <= sizeof name */ + char ch; + + for (;;) { + if (!n) + break; + ch = *buf++; + --n; + if (ch == '.') { + // Don't allow empty labels per http://crbug.com/456391. + if (!labellen) + return false; + if (namelen + labellen + 1 > sizeof name) + return false; + name[namelen++] = static_cast<char>(labellen); + memcpy(name + namelen, label, labellen); + namelen += labellen; + labellen = 0; + continue; + } + if (labellen >= sizeof label) + return false; + label[labellen++] = ch; + } + + // Allow empty label at end of name to disable suffix search. + if (labellen) { + if (namelen + labellen + 1 > sizeof name) + return false; + name[namelen++] = static_cast<char>(labellen); + memcpy(name + namelen, label, labellen); + namelen += labellen; + labellen = 0; + } + + if (namelen + 1 > sizeof name) + return false; + if (namelen == 0) // Empty names e.g. "", "." are not valid. + return false; + name[namelen++] = 0; // This is the root label (of length 0). + + *out = std::string(name, namelen); + return true; +} + +std::string DNSDomainToString(const base::StringPiece& domain) { + std::string ret; + + for (unsigned i = 0; i < domain.size() && domain[i]; i += domain[i] + 1) { +#if CHAR_MIN < 0 + if (domain[i] < 0) + return std::string(); +#endif + if (domain[i] > 63) + return std::string(); + + if (i) + ret += "."; + + if (static_cast<unsigned>(domain[i]) + i + 1 > domain.size()) + return std::string(); + + domain.substr(i + 1, domain[i]).AppendToString(&ret); + } + return ret; +} + +} // namespace net |