]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-20293 strict param validation support
authorskodak <skodak>
Tue, 15 Sep 2009 20:08:47 +0000 (20:08 +0000)
committerskodak <skodak>
Tue, 15 Sep 2009 20:08:47 +0000 (20:08 +0000)
lang/en_utf8/debug.php
lib/moodlelib.php
lib/setuplib.php
lib/simpletest/testmoodlelib.php

index 43f630bb5049159af0d30dd58d1372d9850a862b..3f7bf2b6f3cb20f6c8dfcabc5fec9786e1e6688b 100644 (file)
@@ -15,6 +15,7 @@ $string['erroroccur'] = 'An error has occurred during this process';
 $string['fixsetting'] = 'Please fix your settings in config.php: <p>You have:</p> <p>\$CFG->dirroot = \'$a->current\';</p> <p>but it should be:</p> <p>\$CFG->dirroot = \'$a->found\';</p>';
 $string['invalideventdata'] = 'Incorrect eventadata submitted: $a';
 $string['invalidarraysize'] = 'Incorrect size of arrays in params of $a';
+$string['invalidparameter'] = 'Invalid parameter value detected, execution can not continue.';
 $string['missingconfigversion'] = 'Config table does not contain version, can not continue, sorry.';
 $string['mustbeoveride'] = 'Abstract $a method must be overriden.';
 $string['morethanonerecordinfetch'] = 'Found more than one record in fetch() !';
index edf5400bbcc75471bdb2c3392cac1fdec29b617e..ec7d6dc877183f6e83f0758ea614112869ffffdd 100644 (file)
@@ -374,6 +374,40 @@ function optional_param($parname, $default=NULL, $type=PARAM_CLEAN) {
     return clean_param($param, $type);
 }
 
+/**
+ * Strict validation of parameter values, the values are only converted
+ * to requested PHP type. Internally it is using clean_param, the values
+ * before and after cleaning must be equal - otherwise
+ * an invalid_parameter_exception is thrown.
+ * Onjects and classes are not accepted.
+ *
+ * @param mixed $param
+ * @param int $type PARAM_ constant
+ * @param bool $allownull are nulls valid value?
+ * @param string $debuginfo optional debug information
+ * @return mixed the $param value converted to PHP type or invalid_parameter_exception
+ */
+function validate_param($param, $type, $allownull=true, $debuginfo='') {
+    if (is_null($param)) {
+        if ($allownull) {
+            return null;
+        } else {
+            throw new invalid_parameter_exception($debuginfo);
+        }
+    }
+    if (is_array($param) or is_object($param)) {
+        throw new invalid_parameter_exception($debuginfo);
+    }
+
+    $cleaned = clean_param($param, $type);
+    if ((string)$param !== (string)$cleaned) {
+        // conversion to string is usually lossless
+        throw new invalid_parameter_exception($debuginfo);
+    }
+
+    return $cleaned;
+}
+
 /**
  * Used by {@link optional_param()} and {@link required_param()} to
  * clean the variables and/or cast to specific types, based on
index 791f3f28b9f4d6d4aaa35092f03352a69d1346fb..5f3a5db3ec93a6675bad92ecffab6e6fafb3fc82 100644 (file)
@@ -121,6 +121,22 @@ class coding_exception extends moodle_exception {
     }
 }
 
+/**
+ * Exception indicating malformed parameter problem.
+ * This exception is not supposed to be thrown when processing
+ * user submitted data in forms. It is more suitable
+ * for WS and other low level stuff.
+ */
+class invalid_parameter_exception extends moodle_exception {
+    /**
+     * Constructor
+     * @param string $debuginfo some detailed information
+     */
+    function __construct($debuginfo=null) {
+        parent::__construct('invalidparameter', 'debug', '', null, $debuginfo);
+    }
+}
+
 /**
  * An exception that indicates something really weird happended. For example,
  * if you do switch ($context->contextlevel), and have one case for each
index 76a7717cd98db5934c0505bf156ead804a4ae03c..af3384d87790a729c022bff08daf41072ca30968 100644 (file)
@@ -228,8 +228,7 @@ class moodlelib_test extends UnitTestCase {
         $this->assertEqual(array('gecko', 'gecko19'), get_browser_version_classes());
     }
 
-    function test_optional_param()
-    {
+    function test_optional_param() {
         $_POST['username'] = 'post_user';
         $_GET['username'] = 'get_user';
         $this->assertEqual(optional_param('username', 'default_user', PARAM_CLEAN), 'post_user');
@@ -271,8 +270,7 @@ class moodlelib_test extends UnitTestCase {
      * @param int $type expected format of param after cleaning.
      * @return mixed
      */
-    function test_clean_param()
-    {
+    function test_clean_param() {
         global $CFG;
         // Test unknown parameter type
 
@@ -299,6 +297,45 @@ class moodlelib_test extends UnitTestCase {
         $this->assertEqual(clean_param('course/view.php?id=3', PARAM_LOCALURL), 'course/view.php?id=3');
     }
 
+    function test_validate_param() {
+        try {
+            $param = validate_param('11a', PARAM_INT);
+            $this->fail('invalid_parameter_exception expected');
+        } catch (invalid_parameter_exception $ex) {
+            $this->assertTrue(true);
+        }
+        try {
+            $param = validate_param('11', PARAM_INT);
+            $this->assertEqual($param, 11);
+        } catch (invalid_parameter_exception $ex) {
+            $this->fail('invalid_parameter_exception not expected');
+        }
+        try {
+            $param = validate_param(null, PARAM_INT, false);
+            $this->fail('invalid_parameter_exception expected');
+        } catch (invalid_parameter_exception $ex) {
+            $this->assertTrue(true);
+        }
+        try {
+            $param = validate_param(null, PARAM_INT, true);
+            $this->assertTrue($param===null);
+        } catch (invalid_parameter_exception $ex) {
+            $this->fail('invalid_parameter_exception expected');
+        }
+        try {
+            $param = validate_param(array(), PARAM_INT);
+            $this->fail('invalid_parameter_exception expected');
+        } catch (invalid_parameter_exception $ex) {
+            $this->assertTrue(true);
+        }
+        try {
+            $param = validate_param(new stdClass, PARAM_INT);
+            $this->fail('invalid_parameter_exception expected');
+        } catch (invalid_parameter_exception $ex) {
+            $this->assertTrue(true);
+        }
+    }
+
     function test_make_user_directory() {
         global $CFG;