📄 dbparser.c
字号:
/* dbparser.C * John Viega * * Feb 8 2000 */#include "config.H"#include "token.H"#include "vulndb.H"#include "strpool.H"static TokenContainer *tc;static int next = 0;struct VarInfo{ TokenId type; int val;};static Dictionary<VarInfo> *varlist;static char *cur_var;static char *cur_funcname;TokenId expecting;int *dst_str;int *dst_int;char *current_key_name;int new_desc;int new_repair;int new_severity;int new_handler;int new_input;void InitParser(TokenContainer *t){ tc = t; new_desc = 0; new_repair = 0; new_input = 0; varlist = new Dictionary<VarInfo>(1);}void ParseError(char *s1, char *s2){ fprintf(stderr, "%s:%s: %s (when parsing data file)\n", GetProgramName(), s2, s1);}void ParseError(char *s, Token *t){ if(t) fprintf(stderr, "%s:%d: %s (when parsing data file)\n", GetProgramName(), t->GetLineNo(), s); else fprintf(stderr, "%s: Unexpected end of file (when parsing data file).\n", GetProgramName());}void YieldFunctionDefEnd(){ if(!new_desc) { ParseError("Missing problem description", cur_funcname); exit(11); } if(!new_repair) { ParseError("Missing repair hint", cur_funcname); exit(12); } if((new_severity < 0) || (new_severity > 5)) { ParseError("Invalid severity.", cur_funcname); exit(13); } AddRecord(cur_funcname, new_desc, new_repair, new_severity, new_handler, new_input); new_desc = new_repair = new_input = 0;}void YieldKeyName(char *n){ current_key_name = n; if(!strcasecmp(n, "desc")) { expecting = STRING; dst_str = &new_desc; return; } if(!strcasecmp(n, "solution")) { expecting = STRING; dst_str = &new_repair; return; } if(!strcasecmp(n, "risk")) { expecting = INTEGER; dst_int = &new_severity; return; } if(!strcasecmp(n, "handler")) { expecting = INTEGER; dst_int = &new_handler; return; } if(!strcasecmp(n, "input")) { expecting = INTEGER; dst_int = &new_input; return; } ParseError("Warning: Unrecognized key", n); expecting = COMMENT; // Kludge.}void YieldStringValue(char *s){ switch(expecting) { default: return; // Ignore (Kludge) case INTEGER: fprintf(stderr, "%s:%s: Expected integer value to key '%s', got '%s'.\n", GetProgramName(), cur_funcname, current_key_name, s); exit(14); case STRING: *dst_str = AddStringToPool(s); return; }}void YieldStringValue(int s){ switch(expecting) { default: return; // Ignore (Kludge) case INTEGER: fprintf(stderr, "%s:%s: Expected integer value to key '%s', got var.\n", GetProgramName(), cur_funcname, current_key_name); exit(14); case STRING: *dst_str = s; return; }}void YieldIntegerValue(int t){ switch(expecting) { default: return; // Ignore (Kludge) case STRING: fprintf(stderr, "%s:%s: Expected string value to key '%s', got '%d'.\n", GetProgramName(), cur_funcname, current_key_name, t); exit(15); case INTEGER: *dst_int = t; return; }}int YieldVariableValue(char *s){ VarInfo *v; short ignore; if(!(v = varlist->GetItem(s, ignore))) return -1; switch(v->type) { case INTEGER: YieldIntegerValue(v->val); return 0; default: YieldStringValue(v->val); return 0; }}void YieldFuncName(char *n){ cur_funcname = new char[strlen(n)+1]; strcpy(cur_funcname, n); // ITS4: ignore strcpy new_desc = 0; new_repair = 0; new_severity = 0; new_handler = 0;}void YieldEmptyDefinition(){ delete[] cur_funcname;}void YieldStringAssignment(Token *t){ VarInfo *v = new VarInfo(); if(!v) OutOfMemory(); v->type = STRING; char *val = ((StringTok *)t)->GetContents(); v->val = AddStringToPool(val); varlist->SetItem(cur_var, v);}void YieldIntegerAssignment(Token *t){ VarInfo *v = new VarInfo(); if(!v) OutOfMemory(); v->type = INTEGER; v->val = ((IntegerTok *)t)->GetNumericValue(); varlist->SetItem(cur_var, v); // TODO: Will leak memory if it's already in the varlist. Not a big deal.}void YieldVarName(char *n){ // TODO: Need to copy out the contents to cur_var cur_var = new char[strlen(n)+1]; if(!cur_var) OutOfMemory(); strcpy(cur_var, n); // ITS4: ignore strcpy}int NT_Guts();int NT_Opt(){ Token *t = tc->GetToken(next++); if(!t) { ParseError("',' or '}' expected.", t); return -1; } switch(t->GetTokenType()) { case OPERATOR: if(!strcmp(t->GetValue(), ",")) { return NT_Guts(); } default: --next; return 0; }}int NT_Guts(){ get_1: Token *t = tc->GetToken(next++); if(!t) { id: ParseError("Identifier expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_1; case IDENTIFIER: YieldKeyName(t->GetValue()); break; default: goto id; }get_2: t = tc->GetToken(next++); if(!t) { equals: ParseError("= expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_2; // It's a comment case OPERATOR: if(!strcmp(t->GetValue(), "=")) { break; } // FALLTHROUGH default: goto equals; }get_3: t = tc->GetToken(next++); if(!t) { str_or_int: ParseError("string, integer or identifier expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_3; // It's a comment. case STRING: YieldStringValue(((StringTok *)t)->GetContents()); break; case INTEGER: YieldIntegerValue(((IntegerTok *)t)->GetNumericValue()); break; case IDENTIFIER: if(YieldVariableValue(t->GetValue())) return -1; break; default: goto str_or_int; } return NT_Opt();}int NT_Def(){ get_1: Token *t = tc->GetToken(next++); if(!t) { id: ParseError("Identifier expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_1; case IDENTIFIER: YieldFuncName(t->GetValue()); break; default: goto id; } get_2: t = tc->GetToken(next++); if(!t) { lbrace: ParseError("'{' expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_2; case OPERATOR: if(!strcmp(t->GetValue(), "{")) { break; } default: goto lbrace; } t = tc->GetToken(next); //Probable lookahead, don't incr if(!t) { ParseError("Dictionary entry expected.", t); return -1; } if((t->GetTokenType() == OPERATOR) && !strcmp(t->GetValue(), "}")) { YieldEmptyDefinition(); next++; return 0; } int r = NT_Guts(); if(r) return r; get_4: t = tc->GetToken(next++); if(!t) { rbrace: ParseError("} expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_4; // It's a comment case OPERATOR: if(!strcmp(t->GetValue(), "}")) { YieldFunctionDefEnd(); return 0; } // FALLTHROUGH default: goto rbrace; } return 0; }int NT_Var(){get_1: Token *t = tc->GetToken(next++); if(!t) { equals: ParseError("= expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_1; // It's a comment case OPERATOR: if(!strcmp(t->GetValue(), "=")) { break; } // FALLTHROUGH default: goto equals; }get_2: t = tc->GetToken(next++); if(!t) { str_or_int: ParseError("string or integer expected.", t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_2; // It's a comment. case STRING: YieldStringAssignment(t); break; case INTEGER: YieldIntegerAssignment(t); break; default: goto str_or_int; }get_3: t = tc->GetToken(next++); if(!t) { semi: ParseError("';' expected." , t); return -1; } switch(t->GetTokenType()) { case COMMENT: goto get_3; case OPERATOR: if(!strcmp(t->GetValue(), ";")) return 0; // FALLTHROUGH default: goto semi; }}int NT_Program(){get_1: Token *t = tc->GetToken(next++); int r; if(!t) return 0; switch(t->GetTokenType()) { case IDENTIFIER: break; case COMMENT: goto get_1; default: ParseError("FUNC or identifier expected.", t); return -1; } char *v = t->GetValue(); if(!strcmp(v, "FUNC")) { r = NT_Def(); if(r) return r; } else { YieldVarName(v); r = NT_Var(); if(r) return r; } NT_Program(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -