diff --git a/include/db.php b/include/db.php index a3c2997..ee68963 100644 --- a/include/db.php +++ b/include/db.php @@ -50,10 +50,14 @@ function query_parameters() $data = func_get_args(); $query = $data[0]; - $tokens = split("[\&\?\~]", $query); + $tokens = split("[&?~]", $query); /* NOTE: no need to escape characters inside of [] in regex */ $preparedquery = $tokens[0]; $count = strlen($tokens[0]); + /* do we have the correct number of tokens to the number of parameters provided? */ + if(count($tokens) != count($data)) + return NULL; /* count mismatch, return NULL */ + for ($i=1; $i < count($tokens); $i++) { $char = substr($query, $count, 1); diff --git a/unit_test/run_tests.php b/unit_test/run_tests.php index 0163edf..14bedfb 100644 --- a/unit_test/run_tests.php +++ b/unit_test/run_tests.php @@ -6,6 +6,8 @@ /* TODO: test the rest of the classes we have */ include_once("test_user.php"); +echo "\n"; +include_once("test_db.php"); ?> \ No newline at end of file diff --git a/unit_test/test_common.php b/unit_test/test_common.php new file mode 100644 index 0000000..2cb34b1 --- /dev/null +++ b/unit_test/test_common.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/unit_test/test_db.php b/unit_test/test_db.php new file mode 100644 index 0000000..7b7574d --- /dev/null +++ b/unit_test/test_db.php @@ -0,0 +1,127 @@ +count; + + /* see that '~' strings are replaced with parameters */ + /* NOTE: if the second parameter is quoted this query will produce */ + /* a different number of results than if it was */ + /* NOTE: The second parameter is an example of a SQL injection attack */ + $sQuery = "SELECT count(*) as count from ~ where userid='~'"; + $hResult = query_parameters($sQuery, "user_list", "1' OR 1='1"); + if($hResult) + { + $oRow = mysql_fetch_object($hResult); + if($iUserCount != $oRow->count) + { + echo "sQuery of '".$sQuery."' returned ".$oRow->count." entries instead of the expected ".$iUserCount."\n"; + return false; + } + + if($iUserCount == 0) + { + echo "Because iUserCount is zero we can't know if this test passed or failed\n"; + } + } else + { + echo "sQuery of '".$sQuery."' failed but should have succeeded\n"; + return false; + } + + /** + * test that '&' in a query is properly replaced by the contents from a file + */ + /* write to a file that we will use for the test of '&' */ + $sFilename = "/tmp/test_db.txt"; + $hFile = fopen($sFilename, "wb"); + if($hFile) + { + fwrite($hFile, "user_list"); + fclose($hFile); + + $sQuery = "SELECT count(*) as count from &"; + $hResult = query_parameters($sQuery, $sFilename); + unlink($sFilename); /* delete the temporary file we've created */ + if(!$hResult) + { + echo "sQuery of '".$sQuery."' failed but should have succeeded\n"; + return false; + } + } else + { + echo "Could not open '".$sFilename."' for writing to complete the '&' test\n"; + } + + /** + * test that queries with slashes in them are parameterized properly + * NOTE: this test exists because query_parameters() at one point did not work + * properly with slashes in the query, they were incorrectly being recognized + * as tokens that should be replaced with parameters + */ + $sQuery = "SELECT count(*) as count, '".mysql_real_escape_string("\r\n")."' as x from ?"; + $hResult = query_parameters($sQuery, "user_list"); + if(!$hResult) + { + echo "sQuery of '".$sQuery."' failed but should have succeeded\n"; + return false; + } + + /* test that queries with too many parameters are rejected */ + $sQuery = "SELECT count(*) as count from ?"; + $hResult = query_parameters($sQuery, "user_list", "12"); + if($hResult) + { + echo "sQuery of '".$sQuery."' succeeded but should have failed for too many parameters\n"; + return false; + } + + /* test that queries with too few parameters are rejected */ + $sQuery = "SELECT count(*) as count from ?"; + $hResult = query_parameters($sQuery); + if($hResult) + { + echo "sQuery of '".$sQuery."' succeeded but should have failed for too few parameters\n"; + return false; + } + + return true; +} + + +if(!test_query_parameters()) + echo "test_query_parameters() failed!\n"; +else + echo "test_query_parameters() passed!\n"; + + +?> \ No newline at end of file diff --git a/unit_test/test_user.php b/unit_test/test_user.php index 29bcd92..f40b08a 100644 --- a/unit_test/test_user.php +++ b/unit_test/test_user.php @@ -3,6 +3,7 @@ /* unit tests for user class */ require_once("path.php"); +require_once("test_common.php"); require_once(BASE."include/incl.php"); require_once(BASE."include/user.php"); @@ -11,11 +12,6 @@ require_once(BASE."include/user.php"); $test_email = "testemail@somesite.com"; $test_password = "password"; -function test_start($sFunctionName) -{ - echo $sFunctionName."() starting\n"; -} - /* NOTE: test_user_login() relies on this function leaving the test user */ /* in the database */ function test_user_create()