00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "AstNode.h"
00020 #include "tree.h"
00021 #include "AstContainer.h"
00022 #include "Metric.h"
00023 #include "Utils.h"
00024 #include <cstdlib>
00025 #include <string>
00026 #include <map>
00027 #include <iostream>
00028 #include <stack>
00029 using namespace std;
00030
00031 std::ostream& operator<<(std::ostream& stream, const NumericResult& num) {
00032 stream << num.toString();
00033 return stream;
00034 }
00035
00036 std::ostream& operator<<(std::ostream& stream, const MetricResult& metric) {
00037 stream << "(main=" << metric.main << ')';
00038 for (map<string, NumericResult>::const_iterator iter=metric.storage.begin(); iter!=metric.storage.end();++iter)
00039 stream << '(' << iter->first << "=" << iter->second << ')';
00040 return stream;
00041 }
00042
00043
00044 MetricResult NumberFunctions::operator()(const tree<AstNode>&, const MapClasses* classes , const MapVariables* vars,
00045 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00046 {
00047 MetricResult result;
00048 NumericResult num;
00049
00050 num = func->size();
00051 result.main = num;
00052 return result;
00053 }
00054
00055
00056 MetricResult NumberSinks::operator()(const tree<AstNode>& tr, const MapClasses* classes , const MapVariables* vars,
00057 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00058 {
00059 MetricResult result;
00060 NumericResult num;
00061 unsigned n = 0;
00062
00063 std::map<std::string, BoxedFunction> boxedFunctions = ast->getBoxedFunctions();
00064 for (std::map<std::string, BoxedFunction>::iterator iter=boxedFunctions.begin();iter!=boxedFunctions.end();++iter)
00065 {
00066
00067 bool add = false;
00068 for(MapFunctions::iterator jter=iter->second.output.begin();jter!=iter->second.output.end();++jter) {
00069 if (find(sensitive.begin(), sensitive.end(), jter->first) != sensitive.end()) {
00070 add = true;
00071 break;
00072 }
00073 }
00074 if (add) {
00075 if (find(sensitive.begin(), sensitive.end(), iter->first) == sensitive.end())
00076 sensitive.push_back(iter->first);
00077 }
00078 }
00079
00080
00081 for (tree<AstNode>::iterator iter = tr.begin(); iter != tr.end(); ++iter) {
00082 string t = iter->getType();
00083 if (t == "unticked_function_declaration_statement") {
00084 iter = tr.end(iter);
00085 }
00086 else if (t == "function_call") {
00087 tree<AstNode>::iterator son = tr.begin(iter);
00088 if (son->getType() == "T_STRING") {
00089 tree<AstNode>::iterator textable = tr.begin(son);
00090 if (textable->getType() == "text" && find(sensitive.begin(), sensitive.end(), textable->getValue()) != sensitive.end()) {
00091 n++;
00092 }
00093 }
00094 }
00095 else if (t == "unticked_statement" || t == "expr_without_variable") {
00096 tree<AstNode>::iterator son = tr.begin(iter);
00097 if (utils::start_with(son->getType(), "T_")) {
00098 tree<AstNode>::iterator textable = tr.begin(son);
00099 if (textable->getType() == "text" && find(sensitive.begin(), sensitive.end(), textable->getValue()) != sensitive.end()) {
00100 n++;
00101 }
00102 }
00103 }
00104 }
00105 num = n;
00106 result.main = num;
00107 return result;
00108 }
00109
00110
00111 MetricResult NumberResources::operator()(const tree<AstNode>& tr, const MapClasses* classes , const MapVariables* vars,
00112 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00113 {
00114 MetricResult result;
00115 NumericResult num;
00116 unsigned n = 0;
00117
00118 std::map<std::string, BoxedFunction> boxedFunctions = ast->getBoxedFunctions();
00119 for (std::map<std::string, BoxedFunction>::iterator iter=boxedFunctions.begin();iter!=boxedFunctions.end();++iter)
00120 {
00121
00122 bool add = false;
00123 for(MapFunctions::iterator jter=iter->second.input.begin();jter!=iter->second.input.end();++jter) {
00124 if (find(taintedinput.begin(), taintedinput.end(), jter->first) != taintedinput.end()) {
00125 add = true;
00126 break;
00127 }
00128 }
00129 if (add) {
00130 if (find(taintedinput.begin(), taintedinput.end(), iter->first) == taintedinput.end())
00131 taintedinput.push_back(iter->first);
00132 }
00133 }
00134
00135 for (tree<AstNode>::iterator iter = tr.begin(); iter != tr.end(); ++iter) {
00136 string t = iter->getType();
00137 if (t == "unticked_function_declaration_statement") {
00138 iter = tr.end(iter);
00139 }
00140 else if (t == "function_call") {
00141 tree<AstNode>::iterator son = tr.begin(iter);
00142 if (son->getType() == "T_STRING") {
00143 tree<AstNode>::iterator textable = tr.begin(son);
00144 if (textable->getType() == "text" && find(taintedinput.begin(), taintedinput.end(), textable->getValue()) != taintedinput.end()) {
00145 n++;
00146 }
00147 }
00148 }
00149 else if (t == "unticked_statement" || t == "expr_without_variable") {
00150 tree<AstNode>::iterator son = tr.begin(iter);
00151 if (utils::start_with(son->getType(), "T_")) {
00152 tree<AstNode>::iterator textable = tr.begin(son);
00153 if (textable->getType() == "text" && find(taintedinput.begin(), taintedinput.end(), textable->getValue()) != taintedinput.end()) {
00154 n++;
00155 }
00156 }
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 num = n;
00167 result.main = num;
00168 return result;
00169 }
00170
00171
00172
00173
00174
00175 MetricResult NumberVariables::operator()(const tree<AstNode>&, const MapClasses* classes , const MapVariables* vars,
00176 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00177 {
00178 MetricResult result;
00179 NumericResult num;
00180
00181 num = vars->size();
00182 result.main = num;
00183 return result;
00184 }
00185
00186
00187 MetricResult NumberClasses::operator()(const tree<AstNode>&, const MapClasses* classes , const MapVariables* vars,
00188 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00189 {
00190 MetricResult result;
00191 NumericResult num;
00192
00193 num = classes->size();
00194 result.main = num;
00195 return result;
00196 }
00197
00198
00199 MetricResult NumberInput::operator()(const tree<AstNode>& tr, const MapClasses* classes , const MapVariables* vars,
00200 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00201 {
00202 MetricResult result;
00203 unsigned num=0;
00204
00205 list<string> scanned;
00206 string temp,fullvarname;
00207 const tree<AstNode>* def = defAST.getTreeConstPtr();
00208
00209 for(MapVariables::const_iterator iter=vars->begin(); iter!=vars->end();++iter)
00210 {
00211 for (AstVarBaseList::const_iterator jter=iter->second.begin();jter!=iter->second.end();++jter)
00212 {
00213 temp = jter->name;
00214 fullvarname = jter->name;
00215 if (jter->index.length() > 0) {
00216 fullvarname += ('[' + jter->index + ']');
00217 }
00218 for (tree<AstNode>::leaf_iterator lter=def->begin_leaf();lter!=def->end_leaf();++lter)
00219 {
00220 if (lter->getValue() == temp) {
00221 if (find(scanned.begin(), scanned.end(), fullvarname) == scanned.end()) {
00222
00223 tree<AstNode>::iterator tter=tr.parent(tr.begin(jter->position));
00224 if (tr.number_of_children(tter) > 1)
00225 num++;
00226 scanned.push_back(fullvarname);
00227 }
00228 }
00229 }
00230 }
00231 }
00232 result.main = num;
00233 return result;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 MetricResult NumberDiffuseInputs::operator()(const tree<AstNode>& tr, const MapClasses* classes , const MapVariables* vars,
00246 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00247 {
00248 MetricResult result;
00249 unsigned num=0;
00250
00251 list<string> scanned;
00252 string temp,fullvarname;
00253 const tree<AstNode>* def = defAST.getTreeConstPtr();
00254
00255
00256 for(MapVariables::const_iterator iter=vars->begin(); iter!=vars->end();++iter)
00257 {
00258 for (AstVarBaseList::const_iterator jter=iter->second.begin();jter!=iter->second.end();++jter)
00259 {
00260 temp = jter->name;
00261 fullvarname = jter->name;
00262 if (jter->index.length() > 0) {
00263 fullvarname += ('[' + jter->index + ']');
00264 }
00265 for (tree<AstNode>::leaf_iterator lter=def->begin_leaf();lter!=def->end_leaf();++lter)
00266 {
00267 if (lter->getValue() == temp) {
00268 if (find(scanned.begin(), scanned.end(), fullvarname) == scanned.end()) {
00269
00270 tree<AstNode>::iterator tter=tr.parent(tr.begin(jter->position));
00271 if (tr.number_of_children(tter) > 1)
00272 num++;
00273 scanned.push_back(fullvarname);
00274 }
00275 }
00276 }
00277 }
00278 }
00279
00280
00281
00282 for (MapAssignments::const_iterator iter = assigns->begin(); iter != assigns->end(); ++iter)
00283 {
00284 fullvarname = iter->second.name;
00285 if (iter->second.index.length() > 0) {
00286 fullvarname += ('[' + iter->second.index + ']');
00287 }
00288
00289 string tname = iter->first.name;
00290 if (iter->first.index.length() > 0) {
00291 tname += ('[' + iter->first.index + ']');
00292 }
00293 if (find(scanned.begin(), scanned.end(), fullvarname) != scanned.end()){
00294 num++;
00295 }
00296 }
00297 result.main = num;
00298 return result;
00299 }
00300
00301
00302 MetricResult NumberSunkDiffuseInputs::operator()(const tree<AstNode>& tr, const MapClasses* classes , const MapVariables* vars,
00303 const MapFunctions *func, const MapAssignments *assigns, const MapVarEquivalent *equiv)
00304 {
00305 MetricResult result;
00306 unsigned num = 0;
00307
00308
00309 list<string> scanned, varsList;
00310 list<VarBase> varBaseList;
00311 string temp,fullvarname;
00312 const tree<AstNode>* def = defAST.getTreeConstPtr();
00313
00314 std::map<std::string, BoxedFunction> boxedFunctions = ast->getBoxedFunctions();
00315 for (std::map<std::string, BoxedFunction>::iterator iter=boxedFunctions.begin();iter!=boxedFunctions.end();++iter)
00316 {
00317
00318 bool add = false;
00319 for(MapFunctions::iterator jter=iter->second.output.begin();jter!=iter->second.output.end();++jter) {
00320 if (find(sensitive.begin(), sensitive.end(), jter->first) != sensitive.end()) {
00321 add = true;
00322 cout << "Add this function into sensitive sinks: '" << iter->first << "' because of -- " << jter->first <<endl;
00323 break;
00324 }
00325 }
00326 if (add) {
00327 if (find(sensitive.begin(), sensitive.end(), iter->first) == sensitive.end())
00328 sensitive.push_back(iter->first);
00329 }
00330 }
00331
00332
00333 for(MapVariables::const_iterator iter=vars->begin(); iter!=vars->end();++iter)
00334 {
00335 for (AstVarBaseList::const_iterator jter=iter->second.begin();jter!=iter->second.end();++jter)
00336 {
00337 temp = jter->name;
00338 fullvarname = jter->name;
00339 if (jter->index.length() > 0) {
00340 fullvarname += ('[' + jter->index + ']');
00341 }
00342 for (tree<AstNode>::leaf_iterator lter=def->begin_leaf();lter!=def->end_leaf();++lter)
00343 {
00344 if (lter->getValue() == temp) {
00345 if (find(scanned.begin(), scanned.end(), fullvarname) == scanned.end()) {
00346
00347 tree<AstNode>::iterator tter=tr.parent(tr.begin(jter->position));
00348
00349
00350 scanned.push_back(fullvarname);
00351 varsList.push_back(fullvarname);
00352 varBaseList.push_back(*jter);
00353 }
00354 }
00355 }
00356 }
00357 }
00358
00359
00360 string asname, bsname;
00361
00362 list<string> curVars, forbidden;
00363
00364 for (list<string>::const_iterator jter=varsList.begin(); jter!=varsList.end();++jter)
00365 if (find(curVars.begin(),curVars.end(),*jter) == curVars.end())
00366 curVars.push_back(*jter);
00367 while(curVars.size() > 0)
00368 {
00369
00370 string elmt = *(curVars.begin());
00371
00372 for (MapAssignments::const_iterator iter = assigns->begin(); iter != assigns->end(); ++iter)
00373 {
00374 asname = iter->first.name;
00375 if (iter->first.index.length() > 0) {
00376 asname += ('[' + iter->first.index + ']');
00377 }
00378 bsname = iter->second.name;
00379 if (iter->second.index.length() > 0) {
00380 bsname += ('[' + iter->second.index + ']');
00381 }
00382 if (bsname == elmt && find(forbidden.begin(),forbidden.end(),asname) == forbidden.end()) {
00383 if (find(curVars.begin(),curVars.end(),asname) == curVars.end())
00384 curVars.push_back(asname);
00385 if (find(varsList.begin(),varsList.end(),asname) == varsList.end()) {
00386 varsList.push_back(asname);
00387 varBaseList.push_back(iter->first);
00388 }
00389 }
00390 }
00391 curVars.pop_front();
00392 forbidden.push_back(elmt);
00393 }
00394
00395
00396 for (MapVarEquivalent::const_iterator iter = equiv->begin(); iter != equiv->end(); ++iter)
00397 {
00398 asname = iter->first.name;
00399 if (iter->first.index.length() > 0) {
00400 asname += ('[' + iter->first.index + ']');
00401 }
00402
00403 for (AstVarBaseList::const_iterator jter=iter->second.begin(); jter!=iter->second.end();++jter) {
00404 bsname = jter->name;
00405 if (jter->index.length() > 0) {
00406 bsname += ('[' + jter->index + ']');
00407 }
00408
00409 if (find(varsList.begin(),varsList.end(),bsname) != varsList.end()) {
00410 if (find(varsList.begin(), varsList.end(), asname) == varsList.end()){
00411
00412 varsList.push_back(asname);
00413 varBaseList.push_back(iter->first);
00414 }
00415 }
00416 }
00417 }
00418
00419 cerr << endl << "####################" << endl << "List of variables:" << endl;
00420 for(list<string>::const_iterator k=varsList.begin();k!=varsList.end();++k)
00421 cerr << *k << ',';
00422 cerr << endl << "####################" << endl << endl;
00423
00424 string type,function;
00425 tree<AstNode>::iterator child, parent;
00426
00427 for (tree<AstNode>::iterator iter=tr.begin();iter!=tr.end();++iter)
00428 {
00429 type = iter->getType();
00430
00431 if (type == "function_call"
00432 || (utils::start_with(type, "T_") && (type != "T_CONSTANT_ENCAPSED_STRING" && type != "T_VARIABLE" && type != "T_STRING") )) {
00433
00434 if (type == "function_call")
00435 {
00436
00437 for (tree<AstNode>::iterator jter=iter;jter!=tr.end(iter);++jter) {
00438 if (jter->getType() == "T_STRING") {
00439
00440 child = jter;
00441 break;
00442 }
00443 }
00444
00445 if (tr.number_of_children(child) == 1) {
00446 function = tr.child(child,0)->getValue();
00447 if (find(sensitive.begin(),sensitive.end(),function) != sensitive.end())
00448 {
00449
00450 list<VarBase> subVariables= ast->getSubVariables(iter);
00451
00452
00453
00454
00455
00456
00457 for (list<VarBase>::const_iterator vter=subVariables.begin();vter!=subVariables.end();++vter)
00458 {
00459 string tname = vter->name;
00460 if (vter->index.length() > 0) {
00461 tname += ('[' + vter->index + ']');
00462 }
00463 if (find(varsList.begin(), varsList.end(), tname) != varsList.end()) {
00464
00465 num++;
00466 cerr << "(function_call) Sink |Diffuse input : " << function << " (" << tname << ")" << endl;
00467 break;
00468 }
00469 }
00470 }
00471 }
00472
00473 iter = child;
00474 }
00475 else
00476 {
00477 function = "";
00478
00479 tree<AstNode>::iterator jter = tr.begin(iter);
00480 for (;jter!=tr.end(iter);++jter) {
00481 if (jter->getType() == "text") {
00482 function = jter->getValue();
00483 break;
00484 }
00485 }
00486 if (find(sensitive.begin(),sensitive.end(),function) != sensitive.end())
00487 {
00488
00489
00490 list<VarBase> subVariables= ast->getSubVariables(tr.parent(iter));
00491
00492
00493
00494
00495
00496
00497 for (list<VarBase>::const_iterator vter=subVariables.begin();vter!=subVariables.end();++vter)
00498 {
00499 string tname = vter->name;
00500 if (vter->index.length() > 0) {
00501 tname += ('[' + vter->index + ']');
00502 }
00503
00504 if (find(varsList.begin(), varsList.end(), tname) != varsList.end()) {
00505
00506 num++;
00507 cerr << "(language_dependant) Sink |Diffuse input : " << function << " | " << tname << endl;
00508 break;
00509 }
00510 else
00511 {
00512
00513
00514 if (vter->index.length() > 0)
00515 {
00516
00517 for (list<VarBase>::const_iterator bter=varBaseList.begin();bter!=varBaseList.end();++bter)
00518 {
00519 if (bter->name == vter->name && find(varsList.begin(), varsList.end(), vter->index) == varsList.end()) {
00520
00521 if (vter->index[0] == '$') {
00522 num++;
00523 cerr << "(language_dependant) Sink |Diffuse input : " << function << " | " << tname << endl;
00524 }
00525 break;
00526 }
00527 }
00528 }
00529 }
00530 }
00531 }
00532
00533 iter = jter;
00534 }
00535 }
00536 }
00537
00538
00539
00540 result.main = num;
00541 return result;
00542 }