Exemple #1
0
 public function analyze()
 {
     $atoms = array('Property', 'Staticproperty');
     $this->atomIs($atoms)->hasIn(array('PREPLUSPLUS', 'POSTPLUSPLUS', 'DEFINE', 'CAST'))->back('first');
     $this->prepareQuery();
     $this->atomIs($atoms)->inIs(array('LEFT', 'APPEND'))->atomIs(array('Assignation', 'Arrayappend'))->back('first');
     $this->prepareQuery();
     // arguments : reference variable in a custom function
     $this->atomIs($atoms)->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->functionDefinition()->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank', true)->is('reference', true)->back('first');
     $this->prepareQuery();
     // PHP functions that are references
     $data = new Methods();
     $functions = $data->getFunctionsReferenceArgs();
     $references = array();
     foreach ($functions as $function) {
         if (!isset($references[$function['position']])) {
             $references[$function['position']] = array('\\' . $function['function']);
         } else {
             $references[$function['position']][] = '\\' . $function['function'];
         }
     }
     foreach ($references as $position => $functions) {
         $this->atomIs($atoms)->inIsIE('VARIABLE')->is('rank', $position)->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->atomIs('Functioncall')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR', 'T_UNSET'))->fullnspathIs($functions)->back('first');
         $this->prepareQuery();
     }
     // Class constructors (__construct)
     $this->atomIs($atoms)->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->atomIs('Functioncall')->hasIn('NEW')->classDefinition()->outIs('BLOCK')->outIs('ELEMENT')->analyzerIs('Classes/Constructor')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank')->is('reference', true)->back('first');
     $this->prepareQuery();
 }
Exemple #2
0
 public function analyze()
 {
     $methods = new Methods();
     $nonDeterminist = $methods->getNonDeterministFunctions();
     $nonDeterminist = "'\\\\" . implode("', '\\\\", $nonDeterminist) . "'";
     $whereNonDeterminist = 'where( __.repeat( __.out() ).emit( hasLabel("Functioncall") ).times(' . self::MAX_LOOPING . ').hasLabel("Functioncall").where(__.in("METHOD", "NEW").count().is(eq(0))).has("token", within("T_STRING", "T_NS_SEPARATOR")).filter{ it.get().value("fullnspath") in [' . $nonDeterminist . ']}.count().is(eq(0)) )';
     // foreach with only one value
     $this->atomIs('Foreach')->outIs('VALUE')->atomIs('Variable')->savePropertyAs('code', 'blind')->back('first')->outIs('BLOCK')->raw('where( __.repeat( __.out() ).emit( hasLabel("Variable") ).times(' . self::MAX_LOOPING . ').filter{ it.get().value("fullcode") == blind}.count().is(eq(0)) )')->raw($whereNonDeterminist)->back('first');
     $this->prepareQuery();
     // foreach with key value
     $this->atomIs('Foreach')->outIs('VALUE')->atomIs('Keyvalue')->outIs('KEY')->savePropertyAs('fullcode', 'k')->inIs('KEY')->outIs('VALUE')->savePropertyAs('code', 'v')->inIs('VALUE')->back('first')->outIs('BLOCK')->raw('where( __.repeat( __.out() ).emit( hasLabel("Variable") ).times(' . self::MAX_LOOPING . ').filter{ it.get().value("fullcode") in [v, k]}.count().is(eq(0)) )')->raw($whereNonDeterminist)->back('first');
     $this->prepareQuery();
     // foreach with complex structures (property, static property, arrays, references... ?)
     // for
     $this->atomIs('For')->outIs('INCREMENT')->atomIs('Void')->back('first');
     $this->prepareQuery();
     $this->atomIs('For')->raw('where( __.sideEffect{ blind = []}.out("INCREMENT", "INIT").repeat( out() ).emit( hasLabel("Variable")).times(' . self::MAX_LOOPING . ').sideEffect{ blind.push(it.get().value("code")); }.fold() )')->outIs('BLOCK')->raw('where( __.repeat( __.out() ).emit( hasLabel("Variable") ).times(' . self::MAX_LOOPING . ').filter{ it.get().value("fullcode") in blind}.count().is(eq(0)) )')->raw($whereNonDeterminist)->back('first');
     $this->prepareQuery();
     // for with complex structures (property, static property, arrays, references... ?)
     // do...while
     $this->atomIs('Dowhile')->raw('where( __.sideEffect{ blind = []}.out("CONDITION").repeat( out() ).emit( hasLabel("Variable")).times(' . self::MAX_LOOPING . ').sideEffect{ blind.push(it.get().value("code")); }.fold() )')->outIs('BLOCK')->raw('where( __.repeat( __.out() ).emit( hasLabel("Variable") ).times(' . self::MAX_LOOPING . ').filter{ it.get().value("fullcode") in blind}.count().is(eq(0)) )')->raw($whereNonDeterminist)->back('first');
     $this->prepareQuery();
     // do while with complex structures (property, static property, arrays, references... ?)
     // while
     $this->atomIs('While')->raw('where( __.sideEffect{ blind = []}.out("CONDITION").repeat( out() ).emit( hasLabel("Variable")).times(' . self::MAX_LOOPING . ').sideEffect{ blind.push(it.get().value("code")); }.fold() )')->outIs('BLOCK')->raw('where( __.repeat( __.out() ).emit( hasLabel("Variable") ).times(' . self::MAX_LOOPING . ').filter{ it.get().value("fullcode") in blind}.count().is(eq(0)) )')->raw($whereNonDeterminist)->back('first');
     $this->prepareQuery();
     // while with complex structures (property, static property, arrays, references... ?)
 }
 public function analyze()
 {
     // this is for functions defined within PHP
     $data = new Methods();
     $functions = $data->getFunctionsArgsInterval();
     $argsMins = array();
     $argsMaxs = array();
     foreach ($functions as $function) {
         if ($function['args_min'] > 0) {
             $argsMins[$function['args_min']][] = '\\' . $function['name'];
         }
         if ($function['args_max'] < 100) {
             $argsMaxs[$function['args_max']][] = '\\' . $function['name'];
         }
     }
     foreach ($argsMins as $nb => $f) {
         $this->atomFunctionIs($f)->outIs('ARGUMENTS')->isLess('count', $nb)->back('first');
         $this->prepareQuery();
     }
     foreach ($argsMaxs as $nb => $f) {
         $this->atomFunctionIs($f)->outIs('ARGUMENTS')->isMore('count', $nb)->back('first');
         $this->prepareQuery();
     }
     // this is for custom functions
     $this->atomIs('Functioncall')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->outIs('ARGUMENTS')->savePropertyAs('count', 'args_count')->inIs('ARGUMENTS')->functionDefinition()->analyzerIsNot('Functions/VariableArguments')->outIs('ARGUMENTS')->isMore('args_min', 'args_count')->back('first');
     $this->prepareQuery();
     $this->atomIs('Functioncall')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->outIs('ARGUMENTS')->savePropertyAs('count', 'args_count')->inIs('ARGUMENTS')->functionDefinition()->analyzerIsNot('Functions/VariableArguments')->outIs('ARGUMENTS')->isLess('args_max', 'args_count')->back('first');
     $this->prepareQuery();
 }
Exemple #4
0
 public function analyze()
 {
     $this->atomIs('Variable')->hasIn(array('NOT', 'AT', 'OBJECT', 'NEW', 'RETURN', 'CONCAT', 'SOURCE', 'CODE', 'INDEX', 'CONDITION', 'THEN', 'ELSE', 'KEY', 'VALUE', 'NAME', 'DEFINE', 'PROPERTY', 'METHOD', 'VARIABLE', 'SIGN', 'THROW', 'CAST', 'CASE', 'CLONE', 'FINAL', 'CLASS', 'GLOBAL', 'PPP'));
     $this->prepareQuery();
     // Reading inside an assignation
     $this->atomIs('Variable')->inIs('LEFT')->atomIs('Assignation')->codeIs('=')->hasIn(array('NOT', 'AT', 'OBJECT', 'NEW', 'RETURN', 'CONCAT', 'SOURCE', 'CODE', 'INDEX', 'CONDITION', 'THEN', 'ELSE', 'KEY', 'VALUE', 'NAME', 'DEFINE', 'PROPERTY', 'METHOD', 'VARIABLE', 'SIGN', 'THROW', 'CAST', 'CASE', 'CLONE', 'FINAL', 'CLASS', 'PPP'))->back('first');
     // note : NAME is for Switch!!
     $this->prepareQuery();
     // $this is always read
     $this->atomIs('Variable')->codeIs('$this');
     $this->prepareQuery();
     // right or left, same
     $this->atomIs('Variable')->inIs(array('RIGHT', 'LEFT'))->atomIs(array('Addition', 'Multiplication', 'Logical', 'Comparison', 'Bitshift'))->back('first');
     $this->prepareQuery();
     // right only
     $this->atomIs('Variable')->inIs('RIGHT')->atomIs('Assignation')->back('first');
     $this->prepareQuery();
     // $x++ + 2 (a plusplus within another
     $this->atomIs('Variable')->inIs(array('PREPLUSPLUS', 'POSTPLUSPLUS'))->inIs(array('RIGHT', 'LEFT'))->atomIs(array('Addition', 'Multiplication', 'Logical', 'Comparison', 'Bitshift', 'Assignation'))->back('first');
     $this->prepareQuery();
     // $x++ + 2 (a plusplus in a functioncall
     $this->atomIs('Variable')->inIs(array('PREPLUSPLUS', 'POSTPLUSPLUS'))->hasIn('ARGUMENT')->back('first');
     $this->prepareQuery();
     // variable in a sequence (also useless...)
     $this->atomIs('Variable')->inIs('ELEMENT')->atomIs('Sequence')->back('first');
     $this->prepareQuery();
     // array only
     $this->atomIs('Variable')->inIs('VARIABLE')->atomIs(array('Array', 'Arrayappend'))->back('first');
     $this->prepareQuery();
     // arguments
     $this->atomIs('Function')->outIs('ARGUMENTS')->outIs('ARGUMENT')->atomIs('VARIABLE');
     $this->prepareQuery();
     // arguments : instanceof
     $this->atomIs('Instanceof')->outIs('LEFT')->atomIs('VARIABLE')->back('first');
     $this->prepareQuery();
     // arguments : normal variable in a custom function
     $this->atomIs('Variable')->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->functionDefinition()->inIs('NAME')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank', true)->isNot('reference', true)->back('first');
     $this->prepareQuery();
     // PHP functions that are passed by value
     $data = new Methods();
     $functions = $data->getFunctionsValueArgs();
     $references = array();
     foreach ($functions as $function) {
         if (!isset($references[$function['position']])) {
             $references[$function['position']] = array('\\' . $function['function']);
         } else {
             $references[$function['position']][] = '\\' . $function['function'];
         }
     }
     foreach ($references as $position => $functions) {
         $this->atomIs('Variable')->is('rank', $position)->inIs('ARGUMENT')->inIs('ARGUMENTS')->atomIs('Functioncall')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->fullnspathIs($functions)->back('first');
         $this->prepareQuery();
     }
     // Variable that are not a reference in a functioncall
     $this->atomIs('Variable')->hasIn('ARGUMENT')->hasNoParent('Function', array('ARGUMENT', 'ARGUMENTS'));
     $this->prepareQuery();
 }
Exemple #5
0
 public function dependsOn()
 {
     $data = new Methods();
     $this->bugfixes = $data->getBugFixes();
     $depends = array();
     foreach ($this->bugfixes as $bugfix) {
         if (!empty($bugfix['analyzer'])) {
             $depends[] = $bugfix['analyzer'];
         }
     }
     return $depends;
 }
Exemple #6
0
 public function analyze()
 {
     $dynamicAtoms = array('Variable', 'Property', 'Magicconstant', 'Staticmethodcall', 'Staticproperty');
     //'Functioncall' : if they also have only constants.
     //'Identifier',
     $methods = new Methods();
     $functionList = $methods->getDeterministFunctions();
     $functionList = $this->makeFullNSPath($functionList);
     $this->atomIs(array('Addition', 'Multiplication', 'Concatenation', 'Power', 'Bitshift', 'Logical', 'Not'))->raw('where( __.repeat( out() ).emit( hasLabel("Functioncall") ).times(' . self::MAX_LOOPING . ').hasLabel("Functioncall").filter{ !(it.get().value("fullnspath") in [' . str_replace('\\', '\\\\', $this->SorA($functionList)) . ']) }.count().is(eq(0)) )')->noAtomInside($dynamicAtoms);
     $this->prepareQuery();
     $this->atomFunctionIs(array('\\join', '\\explode', '\\implode', '\\split'))->noAtomInside($dynamicAtoms)->back('first');
     $this->prepareQuery();
 }
Exemple #7
0
 public function analyze()
 {
     $atoms = array('Property', 'Staticproperty');
     $this->atomIs($atoms)->hasIn(array('NOT', 'AT', 'OBJECT', 'NEW', 'RETURN', 'CONCAT', 'SOURCE', 'CODE', 'INDEX', 'CONDITION', 'THEN', 'ELSE', 'KEY', 'VALUE', 'NAME', 'DEFINE', 'PROPERTY', 'METHOD', 'VARIABLE', 'SIGN', 'THROW', 'CAST', 'CASE', 'CLONE', 'FINAL', 'CLASS', 'GLOBAL'));
     // note : NAME is for Switch!!
     $this->prepareQuery();
     // right or left, same
     $this->atomIs($atoms)->inIs(array('RIGHT', 'LEFT'))->atomIs(array('Addition', 'Multiplication', 'Logical', 'Comparison', 'Bitshift'))->back('first');
     $this->prepareQuery();
     // right only
     $this->atomIs($atoms)->inIs('RIGHT')->atomIs('Assignation')->back('first');
     $this->prepareQuery();
     // $x++ + 2 (a plusplus within another
     $this->atomIs($atoms)->inIs(array('PREPLUSPLUS', 'POSTPLUSPLUS'))->inIs(array('RIGHT', 'LEFT'))->atomIs(array('Addition', 'Multiplication', 'Logical', 'Comparison', 'Bitshift', 'Assignation'))->back('first');
     $this->prepareQuery();
     // $x++ + 2 (a plusplus in a functioncall
     $this->atomIs($atoms)->inIs(array('PREPLUSPLUS', 'POSTPLUSPLUS'))->hasIn('ARGUMENT')->back('first');
     $this->prepareQuery();
     // variable in a sequence (also useless...)
     $this->atomIs($atoms)->inIs('ELEMENT')->atomIs('Sequence')->back('first');
     $this->prepareQuery();
     // array only
     $this->atomIs($atoms)->inIs('VARIABLE')->atomIs(array('Array', 'Arrayappend'))->back('first');
     $this->prepareQuery();
     // PHP functions that are passed by value
     $data = new Methods();
     $functions = $data->getFunctionsValueArgs();
     $references = array();
     foreach ($functions as $function) {
         if (!isset($references[$function['position']])) {
             $references[$function['position']] = array('\\' . $function['function']);
         } else {
             $references[$function['position']][] = '\\' . $function['function'];
         }
     }
     foreach ($references as $position => $functions) {
         $this->atomFunctionIs($functions)->outIs('ARGUMENTS')->outWithRank('ARGUMENT', $position)->atomIs($atoms);
         $this->prepareQuery();
     }
     // Variable that are not a reference in a functioncall
     $this->atomIs($atoms)->hasIn('ARGUMENT')->raw('where( __.in("ARGUMENT").in("ARGUMENTS").hasLabel("Function").count().is(eq(0)) )')->analyzerIsNot('Variables/IsRead');
     $this->prepareQuery();
     // Class constructors (__construct)
     // Those are done in the functioncall test
     // Class constructors with self
     $this->atomIs($atoms)->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->atomIs('Functioncall')->codeIs('self')->hasIn('NEW')->classDefinition()->outIs('BLOCK')->outIs('ELEMENT')->_as('method')->outIs('NAME')->analyzerIs('Classes/Constructor')->back('method')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank', true)->isNot('reference', true)->back('first');
     $this->prepareQuery();
     // Class constructors with self
     $this->atomIs($atoms)->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->atomIs('Functioncall')->codeIs('self')->hasIn('NEW')->classDefinition()->outIs('BLOCK')->outIs('ELEMENT')->_as('method')->outIs('NAME')->analyzerIs('Classes/Constructor')->back('method')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank', true)->isNot('reference', true)->back('first');
     $this->prepareQuery();
 }
Exemple #8
0
 public function analyze()
 {
     // Function returning a type, then casted to that type
     $casts = array('T_STRING_CAST' => 'string', 'T_BOOL_CAST' => 'bool', 'T_INT_CAST' => 'int', 'T_ARRAY_CAST' => 'array', 'T_DOUBLE_CAST' => 'real');
     $data = new Methods();
     $returnTypes = $data->getFunctionsByReturn();
     foreach ($casts as $token => $type) {
         $this->atomIs('Cast')->tokenIs($token)->outIs('CAST')->outIsIE('CODE')->atomIs('Functioncall')->fullnspathIs($returnTypes[$type])->back('first');
         $this->prepareQuery();
     }
     // (bool) ($a > 2)
     $this->atomIs('Cast')->tokenIs('T_BOOL_CAST')->outIs('CAST')->outIsIE('CODE')->atomIs('Comparison')->back('first');
     $this->prepareQuery();
 }
 public function analyze()
 {
     $data = new Methods();
     $args = $data->getInternalParameterType();
     $typeConversion = array('string' => array('Magicconstant', 'Heredoc', 'String'), 'real' => 'Real', 'int' => 'Integer', 'numeric' => array('Real', 'Integer'), 'resource' => '', 'bool' => 'Boolean', 'array' => '', 'void' => 'Void', 'mixed' => '');
     foreach ($args as $position => $types) {
         foreach ($types as $type => $functions) {
             if (strpos($type, ',') !== false) {
                 continue;
                 // No support for multiple type yet
             }
             if (!isset($typeConversion[$type]) || empty($typeConversion[$type])) {
                 continue;
             }
             $this->atomIs('Functioncall')->analyzerIs('Functions/IsExtFunction')->fullnspathIs($functions)->outIs('ARGUMENTS')->outIs('ARGUMENT')->is('rank', $position)->isLiteral()->atomIsNot($typeConversion[$type])->back('first');
             $this->prepareQuery();
         }
     }
 }
 public function analyze()
 {
     $data = new Methods();
     $functions = $data->getFunctionsArgsInterval();
     $positions = array();
     foreach ($functions as $function) {
         if ($function['args_min'] == $function['args_max']) {
             continue;
         }
         if ($function['args_max'] == 100) {
             continue;
         }
         // Only test if the last is missing. This is sufficient
         $positions[$function['args_max'] - 1][] = '\\' . $function['name'];
     }
     foreach ($positions as $position => $f) {
         $this->atomFunctionIs($f)->outIs('ARGUMENTS')->noChildWithRank('ARGUMENT', $position)->back('first');
         $this->prepareQuery();
     }
 }
Exemple #11
0
 public function analyze()
 {
     // $a[3]++;
     $this->atomIs('Array')->hasIn(array('PREPLUSPLUS', 'POSTPLUSPLUS', 'DEFINE', 'CAST'))->back('first');
     $this->prepareQuery();
     // $a[1] = 2;
     $this->atomIs('Array')->hasNoIn('VARIABLE')->inIs('LEFT')->atomIs('Assignation')->back('first')->raw('where( __.repeat( __.out("VARIABLE")).emit(hasLabel("Arrayappend")).times(' . self::MAX_LOOPING . ').count().is(eq(0)) )');
     $this->prepareQuery();
     // $a[1][] = 2;
     $this->atomIs('Array')->inIs('APPEND')->atomIs('Arrayappend')->back('first');
     $this->prepareQuery();
     // arguments : reference variable in a custom function
     $this->atomIs('Array')->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->functionDefinition()->inIs('NAME')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank', true)->is('reference', true)->back('first');
     $this->prepareQuery();
     // function/methods definition : all modified by incoming values
     // simple variable
     $this->atomIs('Function')->outIs('ARGUMENTS')->outIs('ARGUMENT')->atomIs('Array');
     $this->prepareQuery();
     // PHP functions that are references
     $data = new Methods();
     $functions = $data->getFunctionsReferenceArgs();
     $references = array();
     foreach ($functions as $function) {
         if (!isset($references[$function['position']])) {
             $references[$function['position']] = array('\\' . $function['function']);
         } else {
             $references[$function['position']][] = '\\' . $function['function'];
         }
     }
     foreach ($references as $position => $functions) {
         $this->atomIs('Array')->is('rank', $position)->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->atomIs('Functioncall')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR', 'T_UNSET'))->fullnspathIs($functions)->back('first');
         $this->prepareQuery();
     }
     // Class constructors (__construct)
     $this->atomIs('Array')->savePropertyAs('rank', 'rank')->inIs('ARGUMENT')->inIs('ARGUMENTS')->hasNoIn('METHOD')->tokenIs(array('T_STRING', 'T_NS_SEPARATOR'))->atomIs('Functioncall')->hasIn('NEW')->classDefinition()->outIs('BLOCK')->outIs('ELEMENT')->analyzerIs('Classes/Constructor')->outIs('ARGUMENTS')->outIs('ARGUMENT')->samePropertyAs('rank', 'rank')->is('reference', true)->back('first');
     $this->prepareQuery();
 }
 public function analyze()
 {
     $data = new Methods();
     $methods = $data->getMethodsArgsInterval();
     $argsMins = array();
     $argsMaxs = array();
     // Needs to finish the list of methods and their arguments.
     // Currently, classes are not checked.
     foreach ($methods as $method) {
         if ($method['args_min'] > 0) {
             $argsMins[$method['args_min']][] = $method['name'];
         }
         $argsMaxs[$method['args_max']][] = $method['name'];
     }
     // case for methods
     foreach ($argsMins as $nb => $f) {
         $this->atomIs(array('Methodcall', 'Staticmethodcall'))->outIs('METHOD')->codeIs($f)->outIs('ARGUMENTS')->isLess('count', $nb)->back('first');
         $this->prepareQuery();
     }
     foreach ($argsMaxs as $nb => $f) {
         $this->atomIs(array('Methodcall', 'Staticmethodcall'))->outIs('METHOD')->codeIs($f)->outIs('ARGUMENTS')->isMore('count', $nb)->back('first');
         $this->prepareQuery();
     }
 }
Exemple #13
0
    public function run()
    {
        $linksIn = Token::linksAsList();
        // processing '\parent' fullnspath
        $query = <<<GREMLIN
g.V().hasLabel("Identifier").filter{ it.get().value("fullnspath").toLowerCase() == "\\\\parent"}
.where( __.until( and( hasLabel("Class"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("EXTENDS") )
.property('fullnspath', __.until( and( hasLabel("Class"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("EXTENDS").values("fullnspath") )
.where( __.until( and( hasLabel("Class"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("EXTENDS").in("DEFINITION") )
.addE('DEFINITION').from( __.until( and( hasLabel("Class"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("EXTENDS").in("DEFINITION") )

GREMLIN;
        $this->gremlin->query($query);
        display("\\parent to fullnspath\n");
        // processing '\self' fullnspath
        $query = <<<GREMLIN
g.V().hasLabel("Identifier").filter{ it.get().value("fullnspath").toLowerCase() == "\\\\self"}
.where( __.until( and( hasLabel("Class", "Interface", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})) )
.property('fullnspath', __.until( and( hasLabel("Class", "Interface", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("NAME").values("fullnspath") )
.addE('DEFINITION').from( __.until( and( hasLabel("Class", "Interface", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})) )

GREMLIN;
        $this->gremlin->query($query);
        display('\\self to fullnspath');
        // processing '\static' fullnspath
        $query = <<<GREMLIN
g.V().hasLabel("Identifier").filter{ it.get().value("fullnspath").toLowerCase() == "\\\\static"}
.where( __.until( and( hasLabel("Class", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})) )
.property('fullnspath', __.until( and( hasLabel("Class", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})).out("NAME").values("fullnspath") )
.addE('DEFINITION').from( __.until( and( hasLabel("Class", "Trait"), __.out("NAME").not(has("atom", "Void")) ) ).repeat(__.in({$linksIn})) )

GREMLIN;
        $this->gremlin->query($query);
        display('\\static to fullnspath');
        // Create link between Class constant and definition
        $query = <<<'GREMLIN'
        g.V().hasLabel('Staticconstant').as('first')
.out('CONSTANT').sideEffect{name = it.get().value("code");}.select('first')
.out('CLASS').hasLabel("Identifier", "Nsname").sideEffect{classe = it.get().value("fullnspath");}.in('DEFINITION')
.where( __.sideEffect{classes = [];}
          .emit(hasLabel("Class")).repeat( out("EXTENDS").in("DEFINITION") ).times(15)
          .out("BLOCK").out("ELEMENT").hasLabel("Const").out("CONST").as('const')
          .out("NAME").filter{ it.get().value("code") == name; }.select('const')
          .sideEffect{classes.add(it.get()); }
          .fold()
)
.map{classes[0]}.as('theClass')
.addE('DEFINITION').from( 'first' )
GREMLIN;
        $this->gremlin->query($query);
        display('Create link between Class constant and definition');
        // Create propertyname for Property Definitions
        $query = <<<GREMLIN
g.V().hasLabel("Ppp", "Var").out("PPP").as("ppp")
.coalesce( out("LEFT"), __.filter{ true } )
.sideEffect{ propertyname = it.get().value('code').toString().substring(1, it.get().value('code').size()); }
.select("ppp")
.sideEffect{ it.get().property('propertyname', propertyname); }

GREMLIN;
        $this->gremlin->query($query);
        display('set propertyname');
        // update fullnspath with fallback for functions
        $query = <<<GREMLIN
g.V().hasLabel("Functioncall").as("a")
                              .has("fullnspath", without(''))
                              .has('token', within('T_STRING', 'T_NS_SEPARATOR'))
                              .where( __.in("NEW", "METHOD").count().is(eq(0)))
                              .sideEffect{ fullnspath = it.get().value("fullnspath")}
                              .in('DEFINITION')
                              .filter{ it.get().value("fullnspath") != fullnspath}
                              .sideEffect{ fullnspath = it.get().value("fullnspath")}
                              .select("a")
                              .sideEffect{ 
                                   it.get().property("fullnspath", fullnspath ); 
                               }

GREMLIN;
        $this->gremlin->query($query);
        display('fallback for global functioncall');
        // update fullnspath with fallback for functions
        $query = <<<GREMLIN
g.V().hasLabel("Functioncall").has("fullnspath", without(''))
                              .has('token', within('T_STRING', 'T_NS_SEPARATOR'))
                              .where( __.in("NEW", "METHOD", "DEFINITION").count().is(eq(0)))

.sideEffect{ 
    fullnspath = it.get().vertices(OUT, 'NAME').next().value("fullnspath").toString().toLowerCase();
    it.get().property("fullnspath", fullnspath ); 
}

GREMLIN;
        $this->gremlin->query($query);
        display('refine functioncall fullnspath');
        // update fullnspath with fallback for functions
        $query = <<<GREMLIN
g.V().hasLabel("Identifier", "Nsname").as("a")
                              .has("fullnspath", without(''))
                              .has('token', within('T_STRING', 'T_NS_SEPARATOR'))
                              .where( __.in("NEW", "METHOD", "NAME", "SUBNAME").count().is(eq(0)))
                              .sideEffect{ fullnspath = it.get().value("fullnspath")}
                              .in('DEFINITION').out("NAME")
                              .filter{ it.get().value("fullnspath") != fullnspath}
                              .sideEffect{ fullnspath = it.get().value("fullnspath")}
                              .select("a")
                              .sideEffect{ 
                                   it.get().property("fullnspath", fullnspath ); 
                               }

GREMLIN;
        $this->gremlin->query($query);
        display('fallback for global constants');
        // fallback for PHP and ext, class, function, constant
        // update fullnspath with fallback for functions
        $pathDocs = $this->config->dir_root . '/data/analyzers.sqlite';
        $docs = new Docs($pathDocs);
        $exts = $docs->listAllAnalyzer('Extensions');
        $exts[] = 'php_constants';
        $c = array();
        $f = array();
        foreach ($exts as $ext) {
            $inifile = str_replace('Extensions\\Ext', '', $ext) . '.ini';
            $fullpath = $this->config->dir_root . '/data/' . $inifile;
            $iniFile = parse_ini_file($fullpath);
            if (!empty($iniFile['constants'][0])) {
                $c[] = $iniFile['constants'];
            }
            if (!empty($iniFile['functions'][0])) {
                $f[] = $iniFile['functions'];
            }
        }
        $constants = call_user_func_array('array_merge', $c);
        $constants = array_filter($constants, function ($x) {
            return strpos($x, '\\') === false;
        });
        $constants = array_map('strtolower', $constants);
        $query = <<<GREMLIN
g.V().hasLabel("Identifier").where( __.in("DEFINITION", "NEW", "USE", "NAME", "EXTENDS", "IMPLEMENTS", "CLASS", "CONST", "CONSTANT", "TYPEHINT", "FUNCTION", "GROUPUSE", "SUBNAME").count().is(eq(0)) )  
                            .filter{ it.get().value("code").toLowerCase() in arg1 }
.sideEffect{ 
    fullnspath = "\\\\" + it.get().value("code").toLowerCase();
    it.get().property("fullnspath", fullnspath); 
}

GREMLIN;
        $this->gremlin->query($query, array('arg1' => $constants));
        display('spot PHP / ext constants');
        $query = 'g.V().hasLabel("Const").out("CONST").out("NAME").filter{ (it.get().value("fullnspath") =~ "^\\\\\\\\[^\\\\\\\\]+\\$" ).getCount() > 0 }.values("code")';
        $constants = $this->gremlin->query($query);
        $constantsGlobal = $constants->results;
        $query = 'g.V().hasLabel("Const").out("CONST").out("NAME").filter{ (it.get().value("fullnspath") =~ "^\\\\\\\\[^\\\\\\\\]+\\$" ).getCount() == 0 }.values("fullnspath")';
        $constants = $this->gremlin->query($query);
        $constantsDefinitions = $constants->results;
        $query = <<<GREMLIN
g.V().hasLabel("Identifier").where( __.in("DEFINITION", "NEW", "USE", "NAME", "EXTENDS", "IMPLEMENTS", "CLASS", "CONST", "CONSTANT", "TYPEHINT", "FUNCTION", "GROUPUSE", "SUBNAME").count().is(eq(0)) )  
                            .filter{ it.get().value("code") in arg1 }
                            .filter{ !(it.get().value("fullnspath").toLowerCase() in arg2) }
                            .sideEffect{ name = it.get().value("code"); }
.sideEffect{ 
    fullnspath = "\\\\" + it.get().value("code").toLowerCase();
    it.get().property("fullnspath", fullnspath); 
}.addE("DEFINITION").from( g.V().hasLabel("Const").out("CONST").out("NAME").filter{ it.get().value("code") == name} )

GREMLIN;
        $this->gremlin->query($query, array('arg1' => $constantsGlobal, 'arg2' => $constantsDefinitions));
        display('spot constants that falls back on global constants');
        $functions = call_user_func_array('array_merge', $f);
        $functions = array_filter($functions, function ($x) {
            return strpos($x, '\\') === false;
        });
        $functions = array_map('strtolower', $functions);
        $query = <<<GREMLIN
g.V().hasLabel("Functioncall").not(has("token", "T_OPEN_TAG_WITH_ECHO"))
                              .filter{ it.get().value("code").toLowerCase() in arg1 }
                              .where( __.in("DEFINITION").count().is(eq(0)) )
.sideEffect{
    fullnspath = "\\\\" + it.get().value("code").toLowerCase();
    it.get().property("fullnspath", fullnspath); 
}

GREMLIN;
        $this->gremlin->query($query, array('arg1' => $functions));
        display('mark PHP native functions call');
        // Define-style constant definitions
        $query = <<<GREMLIN
g.V().hasLabel("Functioncall").has("fullnspath", "\\\\define")
     .out("ARGUMENTS").out("ARGUMENT").has("rank", 0)
     .hasLabel("String").has("noDelimiter")
     .map{ s = it.get().value("noDelimiter").toString().toLowerCase();
           if ( s.substring(0,1) != "\\\\") {
               s = "\\\\" + s;
           }
           it.get().property("fullnspath", s);
           s;
         }.unique();
GREMLIN;
        $constants = $this->gremlin->query($query);
        $constants = $constants->results;
        if (!empty($constants)) {
            // First round, with full ns path
            $query = <<<GREMLIN
g.V().hasLabel("Identifier", "Nsname")
     .where( __.in("NAME", "SUBNAME").count().is(eq(0)) )
     .filter{ it.get().value("fullnspath") in arg1 }.sideEffect{name = it.get().value("fullnspath"); }
     .addE('DEFINITION')
     .from( 
        g.V().hasLabel("Functioncall").has("fullnspath", "\\\\define")
             .out("ARGUMENTS").as("a").out("ARGUMENT").has("rank", 0).hasLabel("String")
             .filter{ it.get().value("fullnspath") == name}.select('a')
         )

GREMLIN;
            $res = $this->gremlin->query($query, array('arg1' => $constants));
            // Second round, with fallback to global constants
            $query = <<<GREMLIN
g.V().hasLabel("Identifier", "Nsname")
     .where( __.in("NAME", "SUBNAME").count().is(eq(0)) )
     .where( __.in("DEFINITION").count().is(eq(0)) )
     .filter{ name = "\\\\" + it.get().value("fullcode").toString().toLowerCase(); name in arg1 }
     .addE('DEFINITION')
     .from( 
        g.V().hasLabel("Functioncall").has("fullnspath", "\\\\define")
             .out("ARGUMENTS").as("a").out("ARGUMENT").has("rank", 0).hasLabel("String")
             .filter{ it.get().value("fullnspath") == name}.select('a')
         )

GREMLIN;
            $res = $this->gremlin->query($query, array('arg1' => $constants));
            // TODO : handle case-insensitive
            display('Link constant definitions');
        } else {
            display('Link constant definitions : skipping.');
        }
        display('Mark literal expressions as constants');
        $query = <<<GREMLIN
g.V().hasLabel("Integer", "Boolean", "Real", "Null", "Void", "InlineHtml", "Magicconstant", "Staticconstant", "Void")
     .sideEffect{ it.get().property("constant", true); }

GREMLIN;
        $this->gremlin->query($query);
        $query = <<<GREMLIN
g.V().hasLabel("String").where( __.out("CONCAT").count().is(eq(0)))
     .sideEffect{ it.get().property("constant", true); }

GREMLIN;
        $this->gremlin->query($query);
        $query = <<<GREMLIN
g.V().hasLabel("Identifier",  "Nsname").not(hasLabel("Functioncall"))
     .sideEffect{ it.get().property("constant", true); }

GREMLIN;
        $this->gremlin->query($query);
        $data = new Methods();
        $deterministFunctions = $data->getDeterministFunctions();
        $deterministFunctions = array_map(function ($x) {
            return '\\' . $x;
        }, $deterministFunctions);
        for ($i = 0; $i < 3; ++$i) {
            // Cases for Structures (all sub element are constante => structure is constante)
            $structures = array('Addition' => array('LEFT', 'RIGHT'), 'Multiplication' => array('LEFT', 'RIGHT'), 'Bitshift' => array('LEFT', 'RIGHT'), 'Logical' => array('LEFT', 'RIGHT'), 'Power' => array('LEFT', 'RIGHT'), 'Keyvalue' => array('KEY', 'VALUE'), 'Arguments' => array('ARGUMENT'), 'Sequence' => array('ELEMENT'), 'Break' => array('BREAK'), 'Continue' => array('CONTINUE'), 'Return' => array('RETURN'), 'Ternary' => array('CONDITION', 'THEN', 'ELSE'), 'Comparison' => array('LEFT', 'RIGHT'), 'Noscream' => array('AT'), 'Not' => array('NOT'), 'Parenthesis' => array('CODE'), 'Concatenation' => array('CONCAT'), 'String' => array('CONCAT'));
            foreach ($structures as $atom => $links) {
                $linksList = "'" . implode("', '", $links) . "'";
                $query = <<<GREMLIN
g.V().hasLabel("{$atom}").where( __.out({$linksList}).not(has("constant", true)).count().is(eq(0)) )
    .sideEffect{ it.get().property("constant", true);}
GREMLIN;
                $this->gremlin->query($query);
            }
            $query = <<<GREMLIN
g.V().hasLabel("Functioncall").filter{ it.get().value("fullnspath") in arg1}
     .where( __.out("ARGUMENTS").out("ARGUMENT").not(has("constant", true)).count().is(eq(0)) )
    .sideEffect{ it.get().property("constant", true);}
GREMLIN;
            $this->gremlin->query($query, array('arg1' => $deterministFunctions));
        }
        display('Mark constants expressions');
        $query = <<<GREMLIN
g.V().hasLabel("Variable").has("code", "\\\$GLOBALS").in("VARIABLE").hasLabel("Array").as("var")
     .out("INDEX").hasLabel("String")
     .sideEffect{ varname = '\$' + it.get().value('noDelimiter');
                  it.get().property("globalvar", varname);}


GREMLIN;
        $this->gremlin->query($query);
        display('Mark constants expressions');
    }
Exemple #14
0
 protected function generateBugfixes()
 {
     $table = '';
     $data = new Methods();
     $bugfixes = $data->getBugFixes();
     $found = $this->sqlite->query('SELECT * FROM results WHERE analyzer = "Php/MiddleVersion"');
     $reported = array();
     $info = array();
     $rows = array();
     while ($row = $found->fetchArray()) {
         $rows[strtolower(substr($row['fullcode'], 0, strpos($row['fullcode'], '(')))] = $row;
     }
     foreach ($bugfixes as $bugfix) {
         if (!empty($bugfix['function'])) {
             if (!isset($rows[$bugfix['function']])) {
                 continue;
             }
             $cve = $this->Bugfixes_cve($bugfix['cve']);
             $table .= '<tr>
 <td>' . $bugfix['title'] . '</td>
 <td>' . ($bugfix['solvedIn71'] ? $bugfix['solvedIn71'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn70'] ? $bugfix['solvedIn70'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn56'] ? $bugfix['solvedIn56'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn55'] ? $bugfix['solvedIn55'] : '-') . '</td>
 <td>' . ($bugfix['solvedInDev'] ? $bugfix['solvedInDev'] : '-') . '</td>
 <td><a href="https://bugs.php.net/bug.php?id=' . $bugfix['bugs'] . '">#' . $bugfix['bugs'] . '</a></td>
 <td>' . $cve . '</td>
             </tr>';
         } elseif (!empty($bugfix['analyzer'])) {
             $subanalyze = $this->sqlite->querySingle('SELECT count FROM resultsCounts WHERE analyzer = "' . $bugfix['analyzer'] . '"');
             $cve = $this->Bugfixes_cve($bugfix['cve']);
             if ($subanalyze == 0) {
                 continue;
             }
             $table .= '<tr>
 <td>' . $bugfix['title'] . '</td>
 <td>' . ($bugfix['solvedIn71'] ? $bugfix['solvedIn71'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn70'] ? $bugfix['solvedIn70'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn56'] ? $bugfix['solvedIn56'] : '-') . '</td>
 <td>' . ($bugfix['solvedIn55'] ? $bugfix['solvedIn55'] : '-') . '</td>
 <td>' . ($bugfix['solvedInDev'] ? $bugfix['solvedInDev'] : '-') . '</td>
 <td><a href="https://bugs.php.net/bug.php?id=' . $bugfix['bugs'] . '">#' . $bugfix['bugs'] . '</a></td>
 <td>' . $cve . '</td>
             </tr>';
         } else {
             continue;
             // ignore. Possibly some mis-configuration
         }
     }
     $html = $this->getBasedPage('bugfixes');
     $html = $this->injectBloc($html, 'BUG_FIXES', $table);
     $this->putBasedPage('bugfixes', $html);
 }
Exemple #15
0
 protected function Bugfixes()
 {
     $css = new \Stdclass();
     $css->displayTitles = true;
     $css->titles = array('Title', 'Solved In 7.0', 'Solved In 5.6', 'Solved In 5.5', 'Solved In php-src', 'bugs.php.net', 'CVE');
     $css->readOrder = $css->titles;
     $data = new Methods();
     $bugfixes = $data->getBugFixes();
     $found = $this->dump->query('SELECT * FROM results WHERE analyzer = "Php/MiddleVersion"');
     $reported = array();
     $info = array();
     $rows = array();
     while ($row = $found->fetchArray()) {
         $rows[strtolower(substr($row['fullcode'], 0, strpos($row['fullcode'], '(')))] = $row;
     }
     foreach ($bugfixes as $bugfix) {
         if (!empty($bugfix['function'])) {
             if (!isset($rows[$bugfix['function']])) {
                 continue;
             }
             $cve = $this->Bugfixes_cve($bugfix['cve']);
             $info[] = array('title' => $bugfix['title'], 'solvedIn70' => $bugfix['solvedIn70'] ? $bugfix['solvedIn70'] : '-', 'solvedIn56' => $bugfix['solvedIn56'] ? $bugfix['solvedIn56'] : '-', 'solvedIn55' => $bugfix['solvedIn55'] ? $bugfix['solvedIn55'] : '-', 'solvedInDev' => $bugfix['solvedInDev'] ? $bugfix['solvedInDev'] : '-', 'bug' => '<a href="https://bugs.php.net/bug.php?id=' . $bugfix['bugs'] . '">#' . $bugfix['bugs'] . '</a>', 'cve' => $cve);
         } elseif (!empty($bugfix['analyzer'])) {
             $subanalyze = $this->dump->querySingle('SELECT COUNT(*) FROM results WHERE analyzer = "' . $bugfix['analyzer'] . '"');
             $cve = $this->Bugfixes_cve($bugfix['cve']);
             if ($subanalyze > 0) {
                 $info[] = array('title' => $bugfix['title'], 'solvedIn70' => $bugfix['solvedIn70'] ? $bugfix['solvedIn70'] : '-', 'solvedIn56' => $bugfix['solvedIn56'] ? $bugfix['solvedIn56'] : '-', 'solvedIn55' => $bugfix['solvedIn55'] ? $bugfix['solvedIn55'] : '-', 'solvedInDev' => $bugfix['solvedInDev'] ? $bugfix['solvedInDev'] : '-', 'bug' => 'ext/' . $bugfix['extension'], 'cve' => $cve);
             }
         } else {
             continue;
             // ignore. Possibly some mis-configuration
         }
     }
     return $this->formatCompilationTable($info, $css);
 }