-1

Let's say that you have a class in php with functions and all that. How could you check if there is no code outside the class? I tried to code this checker with PHP and did it with regex and tokens but nothing worked for me :/

An exmple

<?php
    class example {
        var $name;
        var $password;

        function __construct($name, $password) {
            $this->name = $name;
            $this->password = $password;
        }
----Allowed code----
    }
----Not allowed code----
?>

EDIT: (SOLVED) Thanks @user3163495 for all the information

Here what I did:

1º I tried to get the class name inside the file with this two functions:

function getClass($tokens) {
 $clases = array();
 for($i = 0; $i < count($tokens); $i++) {
     //Tipo del token actual
     $tokenName = getTokenName($tokens, $i);
     if($tokenName === "T_CLASS") {
         //Searchs the name that it has in the file.
         return getClassName($tokens, $i);
     }
 }
 return "";
}

function getClassName($tokens, $i) {
 $index = $i + 1;
 //Line in which is the class inside the file
 $lineaClase = getTokenLine($tokens, $i);
 //Line to be updated while searching
 $lineaTemp = getTokenLine($tokens, $index);
 //Type of token to be updated while searching
 $tokenName = getTokenName($tokens, $index);
 //Searchs in the parsed array for the first class token
 while($index < count($tokens) &&
     $lineaClase === $lineaTemp &&
     ($tokenName === "UNKOWN" || $tokenName === "T_WHITESPACE")) {
     $index++;
     $tokenName = getTokenName($tokens, $index);
     $lineaTemp = getTokenLine($tokens, $index);
 }
 //Returns the name of the class
 return getTokenContent($tokens, $index);
 }

Then, I injected PHP code in the end of the file that I tried to check if it's only a class. Also I saved this new content in a new file called temp.php and finally I shell-executed this to get the echo of the injected code, that will correspond to beginning_of_class:end_of_class. Here is where I used what @user3163495 told me, thank you again.

 function codeInjection($clase, $contenido) {
 //PHP code to inject, thanks to @user3163495
 $codigoPHP = "<?php \$class = new ReflectionClass(\"{$clase}\"); \$comienzo =       \$class->getStartLine(); \$fin = \$class->getEndLine(); echo \$comienzo . \":\" .      \$fin; ?>";
 $contenido .= $codigoPHP;
 //Creating temp file
 file_put_contents("temp.php", $contenido);
 //Returning result of execution
 return shell_exec("php temp.php");
 }

Further, I removed from the token parsed array those tokens which line where between the beginning and the end of the class. Last I go through the array searching for something that is different than a comment, white space, etc..

(Variables are in spanish, if you don't understand the meaning of some feel free to ask)

Joshua
  • 57
  • 4
  • 1
    PHP CodeSniffer is a linter that can check this. I'm not sure of the exact settings, but I think it has this as a check. https://github.com/squizlabs/PHP_CodeSniffer – Reactgular Jun 26 '18 at 19:59
  • 1
    But I wanted to code that functionality myself in PHP in order to check another PHP files @cgTag – Joshua Jun 26 '18 at 20:04
  • In real life I would use a lint tool, but it is a nice exercise to build it in php. Trickier than one might think. Perhaps you should show us what you tried, so we have something to go from. We are not here to write your code, but happy to help. – Pevara Jun 26 '18 at 20:12
  • I've just updated the post with the approach that I followed, thank you! @Pevara – Joshua Jun 27 '18 at 00:42

1 Answers1

0

If you are wanting to "scan" the questionable file from another script to see if there is any code outside the class, then you could use the ReflectionClass in PHP.

Step 1: get the file name that your class is defined in

$class = new ReflectionClass("example");
$fileName = $class->getFileName();

Step 2: get the starting and ending lines of code that the class definition occupies in the file

$startLine = $class->getStartLine();
$endLine = $class->getEndLine();
$numLines = $endLine - $startLine;

Step 3: use file_get_contents() on the file name you obtained in Step 1, and see if there is any forbidden code before the start line or after the end line. You'll have to test and play around with what you get as I don't know exactly where getStartLine() and getEndLine() consider "start" and "end", respectively.

I hope you get the idea.

Some code lifted from this answer: https://stackoverflow.com/a/7909101/3163495

user3163495
  • 2,425
  • 2
  • 26
  • 43
  • Thank you very much! It helped me. I've just updated the post with the approach that I followed. – Joshua Jun 27 '18 at 00:41