فهرست منبع

#2462 Macros: check for number of arguments in macros

Alex Trofimov 7 سال پیش
والد
کامیت
b07b2272bd

+ 32 - 0
inc/classes/BxDolRequest.php

@@ -82,6 +82,38 @@ class BxDolRequest extends BxDol
         BxDolRequest::_error('method', $sMethod, $sModule);
     }
 
+    /**
+     * Check if number of arguments is not less than number of requires arguments
+     * @return  0 - if number of args is correct
+     *          1 - if method or class wasn't found
+     *          2 - if number of args less than number of required arguments
+     *          3 - if number of args more than number of options + required arguments
+     */
+    public static function checkCall($aModule, $sMethod, $aParams, $sClass)
+    {
+        if (isset($aModule['name']) && 'system' == $aModule['name'] && 'Module' == $sClass)
+            $sClass = 'BaseServices';
+        $sMethod = 'service' . bx_gen_method_name($sMethod);
+        $sClass = $aModule['class_prefix'] . $sClass;
+
+        $oModule = BxDolRequest::_require($aModule, $sClass);
+        if($oModule === false)
+            return 1;
+
+        $iArgs = count($aParams);
+        $r = new ReflectionMethod($sClass, $sMethod);
+
+        $iArgsRequired = $r->getNumberOfRequiredParameters();
+        if ($iArgs < $iArgsRequired)
+            return 2;
+
+        $iArgsAll = $r->getNumberOfParameters();
+        if ($iArgs > $iArgsAll)
+            return 3;
+
+        return 0;
+    }
+
     protected static function _perform($aModule, $sClass, $sMethod, $aParams, $bTerminateOnError = true)
     {
         $sClass = $aModule['class_prefix'] . $sClass;

+ 31 - 9
inc/classes/BxDolService.php

@@ -41,14 +41,7 @@ class BxDolService extends BxDol
      */
     public static function call($mixed, $sMethod, $aParams = array(), $sClass = 'Module', $bIgnoreCache = false)
     {
-        $oDb = BxDolModuleQuery::getInstance();
-
-        $aModule = array();
-        if(is_string($mixed))
-            $aModule = $oDb->getModuleByName($mixed);
-        else
-            $aModule = $oDb->getModuleById($mixed);
-
+        $aModule = self::getModule($mixed);
         if (empty($aModule))
             return '';
 
@@ -89,11 +82,13 @@ class BxDolService extends BxDol
         return self::call($a['module'], $a['method'], isset($a['params']) ? $a['params'] : array(), isset($a['class']) ? $a['class'] : 'Module', isset($a['ignore_cache']) ? $a['ignore_cache'] : false);
     }
 
-    public static function callMacro($s, $aMarkers = array(), $sReplaceIn = 'params')
+    public static function callMacro($s, $aMarkers = array())
     {
+        // replace markers
         if ($aMarkers)
             $s = bx_replace_markers($s, $aMarkers);
 
+        // check for correct macros
         if (!preg_match("/^([a-zA-Z0-9_\:]+)(.*)$/", $s, $aMatches))
             return _t('_sys_macros_malformed');
 
@@ -107,11 +102,28 @@ class BxDolService extends BxDol
         if (null === $aParams)
             return _t('_sys_macros_malformed');
 
+        // check if macros is safe
         if (!self::call($a[0], 'is_safe_service', array($a[1])))
             return _t('_sys_macros_unsafe');
 
+        // check module, method and number of arguments
+        $aModule = self::getModule($a[0]);
+        if (empty($aModule))
+            return _t('_sys_macros_method_or_class_not_found');
+        $iCheck = BxDolRequest::checkCall($aModule, $a[1], $aParams, isset($a[3]) ? $a[3] : 'Module');
+        switch ($iCheck) {
+            case 1: 
+                return _t('_sys_macros_method_or_class_not_found');
+            case 2:
+                return _t('_sys_macros_required_args_missing');
+            case 3:
+                return _t('_sys_macros_too_many_args');
+        }
+
+        // perform call
         $mixed = self::call($a[0], $a[1], $aParams, isset($a[3]) ? $a[3] : 'Module', isset($a[4]) && 'ignore_cache' == $a[4] ? true : false);
 
+        // check result
         if (is_object($mixed))
             return _t('_sys_macros_output_not_displayable');
         if (is_array($mixed) && !isset($mixed['content']))
@@ -147,6 +159,16 @@ class BxDolService extends BxDol
 
 		return serialize($aService);
     }
+
+    protected static function getModule($mixed)
+    {
+        $oDb = BxDolModuleQuery::getInstance();
+        if (is_string($mixed))
+            $aModule = $oDb->getModuleByName($mixed);
+        else
+            $aModule = $oDb->getModuleById($mixed);
+        return $aModule;
+    }
 }
 
 /** @} */

+ 3 - 0
modules/boonex/english/data/langs/system/en.xml

@@ -2328,6 +2328,9 @@ If it is not enabled then please consider implement this optimization, since it
     <string name="_sys_macros_malformed"><![CDATA[Error: malformed macros]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Error: unsafe macros]]></string>
     <string name="_sys_macros_output_not_displayable"><![CDATA[Error: output isn't displayable]]></string>
+    <string name="_sys_macros_method_or_class_not_found"><![CDATA[Error: no such macros]]></string>
+    <string name="_sys_macros_required_args_missing"><![CDATA[Error: required arguments are missing]]></string>
+    <string name="_sys_macros_too_many_args"><![CDATA[Error: too many arguments]]></string>
 	<string name="_sys_menu_item_title_about"><![CDATA[About]]></string>
         <string name="_sys_menu_item_title_copyright"><![CDATA[Copyright]]></string>
 	<string name="_sys_menu_item_title_privacy"><![CDATA[Privacy]]></string>

+ 4 - 1
modules/boonex/russian/data/langs/system/ru.xml

@@ -2265,7 +2265,10 @@
 	<string name="_sys_location_undefined"><![CDATA[Отключить местоположение]]></string>
     <string name="_sys_macros_malformed"><![CDATA[Ошибка: некорректный макрос]]></string>
     <string name="_sys_macros_unsafe"><![CDATA[Ошибка: небезопасный макрос]]></string>
-    <string name="_sys_macros_output_not_displayable"><![CDATA[Error: некорректный вывод макроса]]></string>
+    <string name="_sys_macros_output_not_displayable"><![CDATA[Ошибка: некорректный вывод макроса]]></string>
+    <string name="_sys_macros_method_or_class_not_found"><![CDATA[Ошибка: нет такого макроса]]></string>
+    <string name="_sys_macros_required_args_missing"><![CDATA[Ошибка: остутствуют обязательные аргументы]]></string>
+    <string name="_sys_macros_too_many_args"><![CDATA[Ошибка: слишком много аргументов]]></string>
 	<string name="_sys_menu_item_title_about"><![CDATA[О нас]]></string>
         <string name="_sys_menu_item_title_copyright"><![CDATA[Копирайт]]></string>
 	<string name="_sys_menu_item_title_privacy"><![CDATA[Конфиденциальность]]></string>