1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/base/dns_util.h" 6 7 #include <cstring> 8 9 namespace net { 10 11 // Based on DJB's public domain code. 12 bool DNSDomainFromDot(const base::StringPiece& dotted, std::string* out) { 13 const char* buf = dotted.data(); 14 unsigned n = dotted.size(); 15 char label[63]; 16 unsigned int labellen = 0; /* <= sizeof label */ 17 char name[255]; 18 unsigned int namelen = 0; /* <= sizeof name */ 19 char ch; 20 21 for (;;) { 22 if (!n) 23 break; 24 ch = *buf++; 25 --n; 26 if (ch == '.') { 27 if (labellen) { 28 if (namelen + labellen + 1 > sizeof name) 29 return false; 30 name[namelen++] = labellen; 31 memcpy(name + namelen, label, labellen); 32 namelen += labellen; 33 labellen = 0; 34 } 35 continue; 36 } 37 if (labellen >= sizeof label) 38 return false; 39 label[labellen++] = ch; 40 } 41 42 if (labellen) { 43 if (namelen + labellen + 1 > sizeof name) 44 return false; 45 name[namelen++] = labellen; 46 memcpy(name + namelen, label, labellen); 47 namelen += labellen; 48 labellen = 0; 49 } 50 51 if (namelen + 1 > sizeof name) 52 return false; 53 if (namelen == 0) // Empty names e.g. "", "." are not valid. 54 return false; 55 name[namelen++] = 0; // This is the root label (of length 0). 56 57 *out = std::string(name, namelen); 58 return true; 59 } 60 61 std::string DNSDomainToString(const base::StringPiece& domain) { 62 std::string ret; 63 64 for (unsigned i = 0; i < domain.size() && domain[i]; i += domain[i] + 1) { 65 #if CHAR_MIN < 0 66 if (domain[i] < 0) 67 return std::string(); 68 #endif 69 if (domain[i] > 63) 70 return std::string(); 71 72 if (i) 73 ret += "."; 74 75 if (static_cast<unsigned>(domain[i]) + i + 1 > domain.size()) 76 return std::string(); 77 78 domain.substr(i + 1, domain[i]).AppendToString(&ret); 79 } 80 return ret; 81 } 82 83 std::string TrimEndingDot(const base::StringPiece& host) { 84 base::StringPiece host_trimmed = host; 85 size_t len = host_trimmed.length(); 86 if (len > 1 && host_trimmed[len - 1] == '.') { 87 host_trimmed.remove_suffix(1); 88 } 89 return host_trimmed.as_string(); 90 } 91 92 } // namespace net 93