const wchar_t* getRegisteredDomain(const wchar_t* signingDomain, const tldnode* tree) { if (!tree) return NULL; // split domain by . separator, and find tld simutaneously const wchar_t* sDbegin = signingDomain; const wchar_t* sDend = signingDomain + wcslen(signingDomain); reverse_iterator<const wchar_t*> sDrbegin(sDend); reverse_iterator<const wchar_t*> sDrend(sDbegin); reverse_iterator<const wchar_t*> next; const tldnode* subtree = tree; while (sDrend != (next = find(sDrbegin, sDrend, L'.'))) { const tldnode* subnode = findTldNode(subtree, next.base(), (int)(sDrbegin.base() - next.base())); if (subnode == NULL || (subnode->num_children == 1 && subnode->subnodes[0]->attr == THIS)) return sDrbegin.base() != sDend ? next.base() : NULL; subtree = subnode; sDrbegin = next + 1; } if (sDrbegin.base() == sDend) return NULL; const tldnode* subnode = findTldNode(subtree, sDrend.base(), (int)(sDrbegin.base() - sDrend.base())); if (subnode == NULL || (subnode->num_children == 1 && subnode->subnodes[0]->attr == THIS)) return sDrend.base(); return NULL; }
// recursive helper method char* findRegisteredDomain(tldnode* subtree, dlist* dom) { tldnode* subNode = findTldNode(subtree, dom->val); if (subNode==NULL || (subNode->num_children==1 && subNode->subnodes[0]->attr == THIS)) { char* domain = (char*) malloc(strlen(dom->val)+1); strcpy(domain, dom->val); return domain; } else if (dom->next==NULL) { return NULL; } char* fRegDom = findRegisteredDomain(subNode, dom->next); char* concDomain = NULL; if (fRegDom!=NULL) { concDomain = concatDomLabel(fRegDom, dom->val); free(fRegDom); } return concDomain; }
static char * getRegisteredDomainDropI(const char *hostname, const tldnode *tree, int drop_unknown) { // Eliminate some special (always-fail) cases first. if (hostname[0] == '.' || hostname[0] == '\0') return 0; // The registered domain will always be a suffix of the input hostname. // Start at the end of the name and work backward. const char *head = hostname; const char *seg_end = hostname + strlen(hostname); const char *seg_start; if (seg_end[-1] == '.') seg_end--; seg_start = seg_end; for (;;) { while (seg_start > head && *seg_start != '.') seg_start--; if (*seg_start == '.') seg_start++; // [seg_start, seg_end) is one label. const tldnode *subtree = findTldNode(tree, seg_start, seg_end); if (!subtree || (subtree->num_children == 1 && subnodes(subtree)[0]->attr == THIS)) // Match found. break; if (seg_start == head) // No match, i.e. the input name is too short to be a // registered domain. return 0; // Advance to the next label. tree = subtree; if (seg_start[-1] != '.') abort(); seg_end = seg_start - 1; seg_start = seg_end - 1; } // Ensure the stripped domain contains at least two labels. if (!strchr(seg_start, '.')) { if (seg_start == head || drop_unknown) return 0; seg_start -= 2; while (seg_start > head && *seg_start != '.') seg_start--; if (*seg_start == '.') seg_start++; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-qual" return (char *)seg_start; #pragma GCC diagnostic pop }