int GetASNName(const unsigned long asn, char * buffer, const int buffer_length) { int length, rrLength, labelLength ; unsigned char answer[DNS_ANSWER_LENGTH] ; char value[DNS_ANSWER_LENGTH+1] ; HEADER * h ; unsigned char * pRR ; char * lastSlash ; char asn_as_string[13] ; /* Max length of 2*32 as unsigned +3 for null & AS */ snprintf(asn_as_string, 12, "AS%ld", asn) ; #ifdef IP2ASN_DEBUG printf("Querying DNS for the TXT record of %s.asn.cymru.com...\n", asn_as_string) ; #endif length = res_querydomain(asn_as_string, "asn.cymru.com", C_IN, T_TXT, answer, sizeof(answer)); h = (HEADER *) answer ; #ifdef IP2ASN_DEBUG Dump(answer, length) ; printf("First %d bytes:\n", sizeof(HEADER)) ; printf("%d questions\n", ntohs(h->qdcount)) ; printf("%d answers\n", ntohs(h->ancount)) ; printf("%d authority\n", ntohs(h->nscount)) ; printf("%d ressources\n", ntohs(h->arcount)) ; #endif if (ntohs(h->ancount) == 0) { fprintf(stderr, "Received no valid answer from DNS server...\n") ; return -1 ; } else if (ntohs(h->ancount) != 1) { fprintf(stderr, "Received more than 1 answer from DNS server!!!\n") ; } pRR = answer + sizeof(HEADER) ; pRR = skipQuestions(pRR, ntohs(h->qdcount)) ; /* pRR now points to the encoded answer RR */ pRR = skipName(pRR) ; /* Skip the name of the answer to go to the RR type */ if (pRR[0] * 256 + pRR[1] != T_TXT) fprintf(stderr, "Oups... cannot decode the DNS answer part, wrong RR type\n") ; pRR += 2 ; /* Move to RR class */ if (pRR[0] * 256 + pRR[1] != C_IN) fprintf(stderr, "Oups... cannot decode the DNS answer part, wrong RR class\n") ; pRR += 6 ; /* Simply skip RR class + TTL */ rrLength = pRR[0] * 256 + pRR[1] ; /* RRLENGTH */ if (rrLength > DNS_ANSWER_LENGTH) rrLength = DNS_ANSWER_LENGTH ; /* Ugly truncation */ pRR +=2 ; /* Skip the RR length */ labelLength = (unsigned char) *pRR ; memcpy(value, pRR+1, labelLength) ; /* One byte for the label length followed by the label ... assuming a single label here */ value[labelLength] = 0 ; #ifdef IP2ASN_DEBUG printf("TXT(%d) = '%s'\n", labelLength, value) ; #endif /* Response is '16276 | FR | ripencc | 2001-02-15 | OVH OVH Systems' */ lastSlash = rindex(value, '|') ; if (lastSlash == NULL) { return -1 ; } lastSlash ++ ; /* Skip the | */ while ((lastSlash != 0) && (*lastSlash == ' ')) lastSlash++ ; strncpy(buffer, lastSlash, buffer_length) ; buffer[buffer_length-1] = 0 ; /* Just to be sure it is null terminated */ return 0 ; }
static unsigned long int GetASNFromDNS(const char * name, const char * domain) { int length, rrLength, labelLength ; unsigned long int ASN ; unsigned char answer[DNS_ANSWER_LENGTH] ; char value[DNS_ANSWER_LENGTH+1] ; HEADER * h ; unsigned char * pRR ; #ifdef IP2ASN_DEBUG printf("Querying DNS for the TXT record of %s.%s...\n", name, domain) ; #endif length = res_querydomain(name, domain, C_IN, T_TXT, answer, sizeof(answer)); h = (HEADER *) answer ; #ifdef IP2ASN_DEBUG Dump(answer, length) ; printf("First %d bytes:\n", sizeof(HEADER)) ; printf("%d questions\n", ntohs(h->qdcount)) ; printf("%d answers\n", ntohs(h->ancount)) ; printf("%d authority\n", ntohs(h->nscount)) ; printf("%d ressources\n", ntohs(h->arcount)) ; #endif if (ntohs(h->ancount) == 0) { fprintf(stderr, "Received no valid answer from DNS server...\n") ; return -1 ; } else if (ntohs(h->ancount) != 1) { fprintf(stderr, "Received more than 1 answer from DNS server!!!\n") ; } pRR = answer + sizeof(HEADER) ; pRR = skipQuestions(pRR, ntohs(h->qdcount)) ; /* pRR now points to the encoded answer RR */ pRR = skipName(pRR) ; /* Skip the name of the answer to go to the RR type */ if (pRR[0] * 256 + pRR[1] != T_TXT) fprintf(stderr, "Oups... cannot decode the DNS answer part, wrong RR type\n") ; pRR += 2 ; /* Move to RR class */ if (pRR[0] * 256 + pRR[1] != C_IN) fprintf(stderr, "Oups... cannot decode the DNS answer part, wrong RR class\n") ; pRR += 6 ; /* Simply skip RR class + TTL */ rrLength = pRR[0] * 256 + pRR[1] ; /* RRLENGTH */ if (rrLength > DNS_ANSWER_LENGTH) rrLength = DNS_ANSWER_LENGTH ; /* Ugly truncation */ pRR +=2 ; /* Skip the RR length */ labelLength = (unsigned char) *pRR ; memcpy(value, pRR+1, labelLength) ; /* One byte for the label length followed by the label ... assuming a single label here */ value[labelLength] = 0 ; #ifdef IP2ASN_DEBUG printf("TXT(%d) = '%s'\n", labelLength, value) ; #endif if (sscanf(value, "%ld |", &ASN) != 1) { fprintf(stderr,"Cannot extract the ASN from %s\n", value) ; return -1 ; } return ASN ; }
int mp::HTMLParser::Rep::skipAttribute(HTMLParserEvent &event, const char *cp, int *attr_len, const char **value, int *val_len, int *tr) { int v0, v1; int i = skipName(cp); *attr_len = i; *value = NULL; if (!i) return skipSpace(cp); i += skipSpace(cp + i); if (cp[i] == '=') { i++; i += skipSpace(cp + i); if (cp[i] == '\"' || cp[i] == '\'') { *tr = cp[i]; v0 = ++i; while (cp[i] != *tr && cp[i]) i++; v1 = i; if (cp[i]) i++; } else { *tr = 0; v0 = i; while (cp[i] && !strchr(SPACECHR ">", cp[i])) i++; v1 = i; } *value = cp + v0; *val_len = v1 - v0; i += skipSpace(cp + i); } return i; }
static unsigned char * skipQuestions(unsigned char * pRR, const int count) { /* Let's be faithful and trust that we will not overun */ if (count == 0) return pRR ; /* First skip the QName field */ pRR = skipName(pRR) ; return skipQuestions(pRR + 4, count - 1) ; /* Skip again 4 bytes for class and type */ }
void INIFile::readfile(SDL_RWops * file) { SectionRoot = new Section("",0,0); Section* curSection = SectionRoot; std::string completeLine; int lineNum = 0; bool SyntaxError = false; INIFileLine* curLine = NULL; INIFileLine* newINIFileLine; Section* newSection; Key* newKey; bool readfinished = false; while(!readfinished) { lineNum++; completeLine = ""; unsigned char tmp; int readbytes; while(1) { readbytes = SDL_RWread(file,&tmp,1,1); if(readbytes <= 0) { readfinished = true; break; } else if(tmp == '\n') { break; } else if(tmp != '\r') { completeLine += tmp; } } const unsigned char* line = (const unsigned char*) completeLine.c_str(); SyntaxError = false; int ret; ret = getNextChar(line,0); if(ret == -1) { // empty line or comment newINIFileLine = new INIFileLine(completeLine); if(curLine == NULL) { FirstLine = newINIFileLine; curLine = newINIFileLine; } else { curLine->nextLine = newINIFileLine; newINIFileLine->prevLine = curLine; curLine = newINIFileLine; } } else { if(line[ret] == '[') { // section line int sectionstart = ret+1; int sectionend = skipName(line,ret+1); if((line[sectionend] != ']') || (getNextChar(line,sectionend+1) != -1)) { SyntaxError = true; } else { // valid section line newSection = new Section(completeLine,sectionstart,sectionend-sectionstart); if(curLine == NULL) { FirstLine = newSection; curLine = newSection; } else { curLine->nextLine = newSection; newSection->prevLine = curLine; curLine = newSection; } InsertSection(newSection); curSection = newSection; } } else { // might be key/value line int keystart = ret; int keyend = skipKey(line,keystart); if(keystart == keyend) { SyntaxError = true; } else { ret = getNextChar(line,keyend); if((ret == -1) ||(line[ret] != '=')) { SyntaxError = true; } else { int valuestart = getNextChar(line,ret+1); if(valuestart == -1) { SyntaxError = true; } else { if(line[valuestart] == '"') { // now get the next '"' int valueend = getNextQuote(line,valuestart+1); if((valueend == -1) || (getNextChar(line,valueend+1) != -1)) { SyntaxError = true; } else { // valid key/value line newKey = new Key(completeLine,keystart,keyend-keystart,valuestart+1,valueend-valuestart-1); if(FirstLine == NULL) { FirstLine = newKey; curLine = newKey; } else { curLine->nextLine = newKey; newKey->prevLine = curLine; curLine = newKey; } curSection->InsertKey(newKey); } } else { int valueend = skipValue(line,valuestart); if(getNextChar(line,valueend) != -1) { SyntaxError = true; } else { // valid key/value line newKey = new Key(completeLine,keystart,keyend-keystart,valuestart,valueend-valuestart); if(FirstLine == NULL) { FirstLine = newKey; curLine = newKey; } else { curLine->nextLine = newKey; newKey->prevLine = curLine; curLine = newKey; } curSection->InsertKey(newKey); } } } } } } } if(SyntaxError == true) { if(completeLine.size() < 100) { // there are some buggy ini-files which have a lot of waste at the end of the file // and it makes no sense to print all this stuff out. just skip it std::cerr << "INIFile: Syntax-Error in line " << lineNum << ":" << completeLine << " !" << std::endl; } // save this line as a comment newINIFileLine = new INIFileLine(completeLine); if(curLine == NULL) { FirstLine = newINIFileLine; curLine = newINIFileLine; } else { curLine->nextLine = newINIFileLine; newINIFileLine->prevLine = curLine; curLine = newINIFileLine; } } } }
static UXMLNODE parseElement(struct UXMLPARSER *parser, UXMLNODE parent, int *type) { UXMLNODE node; UXMLCHAR *name = parser->offset; size_t nameLength; int isEmpty; if (!skipName(parser)) { setError(parser, 0, "Unexpected end of input parsing stag name"); return NULL; } nameLength = (parser->offset - name); switch (*name) { case '!': { if (stringCompare(name, "![CDATA[", 8)) { *type = UXML_NT_CDATA; return parseCDATA(parser, parent); } else if (stringCompare(name, "!--", 3)) { *type = UXML_NT_COMMENT; return parseComment(parser, parent); } else if (stringCompare(name, "!DOCTYPE", 8)) { *type = UXML_NT_DOCTYPE; return parseDocType(parser, parent); } else { setError(parser, 0, "Unexpected ! tag"); return NULL; } break; } case '?': { if (stringCompare(name, "?xml", 4)) { *type = UXML_NT_PROLOG; return parseProlog(parser, parent); } else { setError(parser, 0, "Unexpected prolog tag"); return NULL; } break; } default: { *type = UXML_NT_ELEMENT; node = parser->createElement(parser, parent, name, nameLength); if (!parseAttributes(parser, node, &isEmpty)) { goto ERROR_DESTROY_NODE; } if (isEmpty) { parser->offset ++; if (*(parser->offset) != '>') { setError(parser, 0, "Unexpected end of input parsing stag name"); goto ERROR_DESTROY_NODE; } parser->offset ++; } else { parser->offset ++; if (!parseContent(parser, node, name, nameLength)) { goto ERROR_DESTROY_NODE; } } break; } } return node; ERROR_DESTROY_NODE: parser->destroyNode(parser, node); return NULL; }
UINLINE static int parseContent(struct UXMLPARSER *parser, UXMLNODE node, const UXMLCHAR *name, size_t nameLength) { UXMLCHAR *content; int type; size_t cchContent; for (;;) { if (!skipWhiteSpace(parser)) { setError(parser, 0, "Unexpected end of input"); return 0; } content = parser->offset; if (!skipUntilLt(parser)) { setError(parser, 0, "Unexpected end of input"); return 0; } cchContent = parser->offset - content; if (cchContent > 0) { parser->createContentNode(parser, node, content, cchContent); } parser->offset ++; //TODO: Validate ahead of offset here, we must not pass beyond parser->end if (*(parser->offset) == '/') { parser->offset ++; if (!stringCompare(parser->offset, name, nameLength)) { setError(parser, 0, "Unmatched end tag of element"); return 0; } if (!skipName(parser)) { setError(parser, 0, "Unexpected end of input while parsing end tag"); return 0; } if (!skipWhiteSpace(parser)) { setError(parser, 0, "Unexpected end of input while parsing end tag"); return 0; } if (*(parser->offset) != '>') { setError(parser, 0, "Unwanted character instead of end of end tag"); return 0; } parser->offset ++; return 1; } if (!parseElement(parser, node, &type)) { return 0; } } }
UINLINE static int parseAttributes(struct UXMLPARSER *parser, UXMLNODE node, int *isEmpty) { for (;;) { UXMLCHAR *attrName; UXMLCHAR *attrValue; size_t attrNameLen; if (!skipWhiteSpace(parser)) { setError(parser, 0, "Unexpected end of input looking for attribute or stag end"); return 0; } if (*parser->offset == '/') { *isEmpty = 1; return 1; } if (*parser->offset == '>') { *isEmpty = 0; return 1; } attrName = parser->offset; if (!skipName(parser)) { setError(parser, 0, "Unexpected end of input parsing attribute name"); return 0; } attrNameLen = parser->offset - attrName; if (!skipWhiteSpace(parser)) { setError(parser, 0, "Unexpected end of input parsing attribute name"); return 0; } if (*(parser->offset++) != '=') { setError(parser, 0, "Unexpected character when looking for '='"); return 0; } if (!skipWhiteSpace(parser)) { setError(parser, 0, "Unexpected end of input parsing attribute name"); return 0; } switch (*(parser->offset++)) { case '\"': attrValue = parser->offset; if (!skipUntilDoubleQuote(parser)) { setError(parser, 0, "Unexpected character when looking for double quote"); return 0; } break; case '\'': attrValue = parser->offset; if (!skipUntilSingleQuote(parser)) { setError(parser, 0, "Unexpected character when looking for double quote"); return 0; } break; default: setError(parser, 0, "Unexpected character when looking for attribute name"); return 0; } parser->setAttribute(parser, node, attrName, attrNameLen, attrValue, parser->offset - attrValue); parser->offset ++; } }
void IniFile::readFile() { if((SectionRoot = new SectionEntry("",0,0)) == nullptr) throw(std::bad_alloc()); SectionEntry *curSectionEntry = SectionRoot; std::string completeLine; int lineNum = 0; bool SyntaxError = false; CommentEntry *curEntry = nullptr; CommentEntry *newCommentEntry; SectionEntry *newSectionEntry; KeyEntry *newKeyEntry; bool readfinished = false; while(!readfinished) { lineNum++; completeLine = ""; uint8_t tmp; size_t size = _stream.sizeg(); while(static_cast<uint32_t>(_stream.tellg()) < size-1) { tmp = _stream.get(); if(static_cast<uint32_t>(_stream.tellg()) == size-1) { readfinished = true; break; } else if(tmp == '\n') { break; } else if(tmp != '\r') { completeLine += tmp; } } const uint8_t *line = reinterpret_cast<const uint8_t*>(completeLine.c_str()); SyntaxError = false; int ret; ret = getNextChar(line,0); if(ret == -1) { // empty line or comment if((newCommentEntry = new CommentEntry(completeLine)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newCommentEntry; curEntry = newCommentEntry; } else { curEntry->nextEntry = newCommentEntry; newCommentEntry->prevEntry = curEntry; curEntry = newCommentEntry; } } else { if(line[ret] == '[') { // section line int sectionstart = ret+1; int sectionend = skipName(line,ret+1); if((line[sectionend] != ']') || (getNextChar(line,sectionend+1) != -1)) { SyntaxError = true; } else { // valid section line if((newSectionEntry = new SectionEntry(completeLine,sectionstart,sectionend-sectionstart)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newSectionEntry; curEntry = newSectionEntry; } else { curEntry->nextEntry = newSectionEntry; newSectionEntry->prevEntry = curEntry; curEntry = newSectionEntry; } InsertSection(newSectionEntry); curSectionEntry = newSectionEntry; } } else { // might be key/value line int keystart = ret; int keyend = skipKey(line,keystart); if(keystart == keyend) { SyntaxError = true; } else { ret = getNextChar(line,keyend); if((ret == -1) ||(line[ret] != '=')) { SyntaxError = true; } else { int valuestart = getNextChar(line,ret+1); int valueend; if(valuestart == -1) { SyntaxError = true; } else { if(line[valuestart] == '"') { // now get the next '"' valueend = getNextQuote(line,valuestart+1); if((valueend == -1) || (getNextChar(line,valueend+1) != -1)) { SyntaxError = true; } else { // valid key/value line if((newKeyEntry = new KeyEntry(completeLine,keystart,keyend-keystart,valuestart+1,valueend-valuestart-1)) == nullptr) throw(std::bad_alloc()); if(FirstLine == nullptr) { FirstLine = newKeyEntry; curEntry = newKeyEntry; } else { curEntry->nextEntry = newKeyEntry; newKeyEntry->prevEntry = curEntry; curEntry = newKeyEntry; } InsertKey(curSectionEntry,newKeyEntry); } } else { valueend = skipValue(line,valuestart); if(getNextChar(line,valueend) != -1) { SyntaxError = true; } else { // valid key/value line if((newKeyEntry = new KeyEntry(completeLine,keystart,keyend-keystart,valuestart,valueend-valuestart)) == nullptr) throw(std::bad_alloc()); if(FirstLine == nullptr) { FirstLine = newKeyEntry; curEntry = newKeyEntry; } else { curEntry->nextEntry = newKeyEntry; newKeyEntry->prevEntry = curEntry; curEntry = newKeyEntry; } InsertKey(curSectionEntry,newKeyEntry); } } } } } } } if(SyntaxError == true) { if(completeLine.size() < 100) { // there are some buggy ini-files which have a lot of waste at the end of the file // and it makes no sense to print all this stuff out. just skip it std::cerr << "IniFile: Syntax-Error in line " << lineNum << ":" << completeLine << " !" << std::endl; } // save this line as a comment if((newCommentEntry = new CommentEntry(completeLine)) == nullptr) throw(std::bad_alloc()); if(curEntry == nullptr) { FirstLine = newCommentEntry; curEntry = newCommentEntry; } else { curEntry->nextEntry = newCommentEntry; newCommentEntry->prevEntry = curEntry; curEntry = newCommentEntry; } } } }
void mp::HTMLParser::Rep::parse_str(HTMLParserEvent &event, const char *cp) { const char *text_start = cp; while (*cp) { if (*cp++ != '<') continue; if (nest && *cp == '!') { int i; tagText(event, text_start, cp - 1); if (cp[1] == '-' && cp[2] == '-') { for (i = 3; cp[i]; i++) if (cp[i] == '-' && cp[i+1] == '-' && cp[i+2] == '>') { i+= 2; event.openTagStart(cp, i); break; } } else { for (i = 1; cp[i] && cp[i] != '>'; i++) ; event.openTagStart(cp, i); } if (m_verbose) printf("------ dtd %.*s\n", i, cp); i += tagEnd(event, cp, i, cp + i); cp += i; text_start = cp; } else if (nest && *cp == '?') { int i; tagText(event, text_start, cp - 1); for (i = 1; cp[i] && cp[i] != '>'; i++) ; event.openTagStart(cp, i); if (m_verbose) printf("------ pi %.*s\n", i, cp); i += tagEnd(event, cp, i, cp + i); cp += i; text_start = cp; } else if (*cp == '/' && isAlpha(cp[1])) { int i; i = skipName(++cp); if (!nest) { if (i == 6 && !yaz_strncasecmp(cp, "script", i)) { int ws = skipSpace(cp + 6); if (cp[ws + 6] == '>') nest = true; /* really terminated */ } if (!nest) continue; } tagText(event, text_start, cp - 2); event.closeTag(cp, i); if (m_verbose) printf("------ tag close %.*s\n", i, cp); i += tagEnd(event, cp, i, cp + i); cp += i; text_start = cp; } else if (nest && isAlpha(*cp)) { int i, j; tagText(event, text_start, cp - 1); i = skipName(cp); event.openTagStart(cp, i); if (m_verbose) printf("------ tag open %.*s\n", i, cp); j = tagAttrs(event, cp, i, cp + i); j += tagEnd(event, cp, i, cp + i + j); if (i == 6 && !yaz_strncasecmp(cp, "script", i)) nest = false; cp += i + j; text_start = cp; } } tagText(event, text_start, cp); }