📄 scanner.c
字号:
/* scanner.C * John Viega * * Jan 28-29 2000 */#include "config.H"#include "scanner.H"#include "fatal.H"void Scanner::ProcessIgnores(){ TokenContainer *cc = lexer->GetComments(); int i = 0; // assert forall i[0:cc.size]: cc->GetToken(i)->GetTokenType() == COMMENT while(1) { CommentTok *tok = (CommentTok *)(cc->GetToken(i++)); if(!tok) break; char *str = tok->GetValue(); Lex *l = new Lex(str, strlen(str), lexer->GetSourceIdentifier(), tok->GetLineNo(), 1, 1); if(!l) OutOfMemory(); TokenContainer *tc = l->GetTokens(); CheckOneContainer(tc, tok); delete l; }}void Scanner::CheckOneContainer(TokenContainer *tc, CommentTok *comment_tok){ Token *t = tc->GetToken(0); if(!t) return; TokenId id = t->GetTokenType(); if(id != IDENTIFIER) return; if(strcasecmp(((IdTok *)t)->GetName(), "ITS4")) // If value != ITS4 return; t = tc->GetToken(1); if(!t) return; id = t->GetTokenType(); if(id != OPERATOR) return; if(strcmp(((OperatorTok *)t)->GetOperatorName(), ":")) return; FigureOutCommand(tc, comment_tok);}void Scanner::CalculateEffectiveLineNumber(CommentTok *comment_tok, int &l1, int &l2){ int start_line = comment_tok->GetLineNo(); int end_line = comment_tok->GetEndLineNo(); int tok_ix = comment_tok->GetTokenIndex(); int start_yes = 0; int end_yes = 0; // Note: This should ignore both lines: /* Non-commented-stuff */ /* * ITS4: IGNORE */ /*Non-commented-stuff*/ TokenContainer *tc = lexer->GetTokens(); Token *t; int i = 0; do { t = tc->GetToken(tok_ix-(++i)); } while(t && (t->GetTokenType() == COMMENT) && t->GetLineNo() == start_line); if(t) { if((t->GetLineNo() == start_line) && (t->GetTokenType() != COMMENT)) { start_yes = 1; } } i = 0; if(!start_yes) { do { t = tc->GetToken(tok_ix+(++i)); } while(t && (t->GetTokenType() == COMMENT) && t->GetLineNo() == end_line); if(t) { if((t->GetLineNo() == end_line) && (t->GetTokenType() != COMMENT)) { end_yes = 1; } } } if(start_yes || end_yes) { l1 = start_line; l2 = end_line; } else { l1 = l2 = end_line+1; }}void Scanner::FigureOutCommand(TokenContainer *tc, CommentTok *comment_tok){ int i,x; LineIgnoreList *ilist = 0; Token *t = tc->GetToken(2); if(!t || (t->GetTokenType() != IDENTIFIER)) { goto invalid; } if(strcasecmp(((IdTok *)t)->GetName(), "IGNORE")) { goto invalid; } int l1, l2; CalculateEffectiveLineNumber(comment_tok, l1, l2); ilist = new LineIgnoreList(l1, l2, comment_tok->GetTokenIndex()); if(!ilist) OutOfMemory(); i = 3; x = 0; while(1) { t = tc->GetToken(i++); if(!t) { AddToBigIgnoreList(ilist); return; } char *str; char *cpy; switch(t->GetTokenType()) { case IDENTIFIER: if(!ilist->ignore) { char **arr = new char* [tc->GetCurrentSize()]; if(!arr) OutOfMemory(); ilist->ignore = arr; } str = ((IdTok *)t)->GetName(); cpy = new char[strlen(str)+1]; if(!cpy) OutOfMemory(); strcpy(cpy, str); /* its4: ignore strcpy */ ilist->ignore[x++] = cpy; ilist->ignore[x] = 0; continue; case OPERATOR: if(!strcmp(((OperatorTok *)t)->GetOperatorName(), ",")) continue; /* fallthrough */ default: goto invalid; } } invalid: delete ilist; fprintf(stderr, "%s:%d: WARNING: Invalid ITS4 command." NEWLINE, lexer->GetSourceIdentifier(), t->GetLineNo()); return;}void Scanner::RunScan(){ ProcessIgnores(); TokenContainer *tc = lexer->GetTokens(); Token *tok; IdTok *itok; int i = 0; int ignore_stream = 0; while(1) { tok = tc->GetToken(i++); if(!tok) break; TokenId id = tok->GetTokenType(); char *name; switch(id) { case IDENTIFIER: if(ignore_stream) continue; itok = (IdTok *)tok; name = itok->GetName(); if(!Paranoid()) { tok = tc->GetToken(i); if(tok && ((tok->GetTokenType() != OPERATOR) || strcmp(((OperatorTok *)tok)->GetOperatorName(), "("))) { continue; } } CheckName(name, tc, i, itok->GetLineNo(), itok->GetEndLineNo()); continue; case PREPROC_START: tok = tc->GetToken(i++); if(tok && (tok->GetTokenType() != STRING)) { if(strcmp(((StringTok *)tok)->GetContents(), "define")) { ignore_stream = 1; } } continue; case PREPROC_END: ignore_stream = 0; continue; default: continue; } }}void Scanner::CheckName(char *name, TokenContainer *tc, int i, int startline, int endline){ // First look and see if we should be ignoring this due to an ITS4: command. if(IgnoreItOrNo(name, startline, endline, i-1)) { return; } VulnInfo *v = GetVulnInfo(name); if(!v) return; if(GetInputScanning() && !v->input) return; if(!GetUseHandlers()) { DefaultHandler(v, tc, i, lexer->GetSourceIdentifier()); return; } switch(v->handler) { case 0: DefaultHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 1: StrcpyHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 2: SprintfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 3: SnprintfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 4: ScanfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 5: SscanfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 6: TOCTOU_A_Handler(v, tc, i, lexer->GetSourceIdentifier()); break; case 7: TOCTOU_B_Handler(v, tc, i, lexer->GetSourceIdentifier()); break; case 8: TOCTOU_C_Handler(v, tc, i, lexer->GetSourceIdentifier()); break; case 9: FprintfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 10: PrintfHandler(v, tc, i, lexer->GetSourceIdentifier()); break; case 11: SyslogHandler(v, tc, i, lexer->GetSourceIdentifier()); break; default: fprintf(stderr, "Undefined handler: %d\nUsing default.", v->handler); DefaultHandler(v, tc, i, lexer->GetSourceIdentifier()); break; }}int Scanner::IgnoreItOrNo(char *id, int start_line, int end_line, int token_index){ if(IgnoreIts4Commands()) return 0; LineIgnoreList *cur = ignore_ptr ? *ignore_ptr : 0; if(!cur) return 0; while(start_line > cur->line_end) { if(!cur->next) return 0; /* Don't ignore it. */ ignore_ptr = &(cur->next); cur = *ignore_ptr; } try_again: // If the next ignore item is still to come, return 0 (don't ignore). if(end_line < cur->line_start) return 0; if(cur->scope_ends_at_token) { if(cur->token_number < token_index) { ignore_ptr = &(cur->next); cur = *ignore_ptr; goto try_again; } } if(cur->scope_starts_at_token) { if(cur->token_number > token_index) return 0; } if(!(cur->ignore)) return 1; // Ignore everything on this line. int i = 0; char *s; while(1) { s = cur->ignore[i++]; if(!s) return 0; if(!strcmp(s,id)) return 1; } /* NOTREACHED */}void Scanner::AddToBigIgnoreList(LineIgnoreList *p){ if(!ignore_data_start) { ignore_data_end = ignore_data_start = p; return; } if(ignore_data_end->line_end == p->line_start) { if(!ignore_data_end->ignore && !p->ignore) { // Extend scope, but add no new information. ignore_data_end->line_end = p->line_end; delete p; return; } else { ignore_data_end->scope_ends_at_token = 1; p->scope_starts_at_token = 1; } } ignore_data_end->next = p; ignore_data_end = p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -