Re: [SMARTY-DEV] Re: Smarty and object support

From: Date: Tue, 17 Dec 2002 17:08:17 +0000
Subject: Re: [SMARTY-DEV] Re: Smarty and object support
References: 1 2 3  Groups: php.smarty.dev 
Request: Send a blank email to php-smarty-dev+get-428@lists.php.net to get a copy of this message
Yep, basically you are right. The proplem for me is that I use alot of constants for example to check access rights within the template. Here's a real-life example: {if $nextgen->user->isAuthorized(null, null, _NGAUTH_EDIT)} <a href="{ng_moduleurl ...}">edit</a> {/if} I try to convert this to the a new and more flexible syntax but not all templates can be edited in such a short time. {ng_auth access=_AUTH_EDIT} <a href="{ng_moduleurl ...}">edit</a> {/ng_auth} Other constants are used to classify special function so you don't need to remember complex function names (consisting of a module name, a context and the real name). {ng_moduleurl module="MyModule" context=_FUNCTYPE_USER func="MyFunction"} etc. I COULD assign all constants to the templates but this would be an overhead and you couldn't easily distinguish between variables and constants anymore. Okay, using a syntax like $_CONSTANT would be possible but I don't like it really ;-) What do you think about a Smarty Security flag. Something like ("ALLOW_CONSTANTS" => true // allows templates to use constants defined in PHP namespace ? > {$foo->bar(passthru("cat /etc/passwd"))} This will not be recognized as valid tag. Check the source modifications. Such constructs are NOT allowed because passthrough is a function neither an object not an object method. But one bug I already know: I allow other thing than variables, objects, constants and NULL, TRUE, FALSE. You can call things like {$foo->bar(die)} which isn't very nice but this could be fixed I think. Perhaps I implement a check so only the following is allowed: - variables beginning with "$" - objects and object methods ( $object and $object->[...->]method() ) - TRUE / FALSE (perhaps also ON / OFF / YES / NO) - NULL and - Constants, if Security Flag "ALLOW_CONSTANTS" is set to true and it's defined as a constant (using PHP constant() or get_defined_constants() method). This way we avoid security holes, don't we? > Basically, an object call in your template is no different than a > template function call. You call an object method to retrieve some text. > These methods can take any number of values as parameters. These values > should be limited to the same syntax we allow for template function > parameters. Exactly! Using the newest CVS you already allow {myFunc param1=$foo->bar()}. Also you allow {myFunc param=$foo->bar("$blah")} and even {$foo->bar("$blah")}. Using {myObj->myFunc($foo->bar())} dosn't work. But why? Where's the BIG difference to not allow such a syntax? > {$foo->bar($foo->bar("lala",$foo->_bar('foo','bar')); > > If we support this, we have to recursively parse and test for security > (private function calls, etc.), function calls, etc. I already parse these constructs recursively by calling Smarty_Compiler::_parse_vars_props for each (!) argument of the method. So only vars (and Constants with my other modification) are allowed as argument! By the way "(...)" syntax is only allowed for object methods: {$foo->bar()} is okay, but {$foo->$bar()} is rejected already. So you cannot do really weired things like $$bar etc. what whould be a high security risk. If you would implement a check for "->_\w+" and "->__\w+" in Smarty_Compiler::_parse_vars_props a simple "is an private method or variable is addressed?" check could be implemented. > Design your objects > and apps so the templates keep a minimal syntax. > Okay, that's right. Nothing to say more ;-) Btw: You referenced an old posting by myself, check the newer one with an CVS diff attached. These are the final changes made by me with the features meantioned. Thanks for interest, André "Monte Ohrt" <monte@ispi.net> schrieb im Newsbeitrag news:1040141060.7422.60.camel@lena.ispi.prv... > Allowing multiple parameters, OK that's a given. But nesting objects as > parameters, allowing constants, etc. is NOT good IMHO. > > Basically, an object call in your template is no different than a > template function call. You call an object method to retrieve some text. > These methods can take any number of values as parameters. These values > should be limited to the same syntax we allow for template function > parameters. > > Example: > > {$foo->bar("foobar",$foobar,#foobar#,%foobar%)} > > > Here's where I see problems with the others: > > {$foo->bar(_MY_CONSTANT)} > > Why allow a constant in the templates? Perceptively, templates know > nothing about constants. If you want to use a constant, assign it and > use $_MY_CONSTANT. We should stick to assigned values. I know that null > is useful, so _maybe_ we'll allow null, although I'd lean toward > sticking to rules and make $smarty.null available instead. > > {$foo->bar(passthru("cat /etc/passwd"))} > > Obvious problems, so no functions as parameters. You shouldn't need that > in the templates anyways. If you do, think again and redesign your > object/application. > > {$foo->bar($foo->bar("lala",$foo->_bar('foo','bar')); > > If we support this, we have to recursively parse and test for security > (private function calls, etc.), function calls, etc. Design your objects > and apps so the templates keep a minimal syntax. > > Thoughts? > > > > > On Tue, 2002-12-17 at 03:00, André Rabold wrote: > > Great work! It works for me but there is one annoyance: > > > > {$foo->bar('blah','blub')} doesn't work because you only check > > for one > > parameter. > > I have modified Smarty_Compiler to allow multiple ones: > > > > Index: Smarty_Compiler.class.php > > =================================================================== > > RCS file: /repository/smarty/Smarty_Compiler.class.php,v > > retrieving revision 1.135 > > diff -r1.135 Smarty_Compiler.class.php > > 238c238 > > < if > > (preg_match('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+(?:\((?:' > > . $this->_qstr_regexp . ')*\))*))*(?>\|@?\w+(:(?>' . > > $this->_qstr_regexp . > > '|[^|]+))*)*$!', $tag_command) || // if a variable > > --- > > > if > > (preg_match('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+(?:\((?:' > > . $this->_qstr_regexp . > > > > ')*(\s*,\s*(?:'.$this->_qstr_regexp.')*)*\))*))*(?>\|@?\w+(:(?>' . > > $this->_qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // if a variable > > 1077c1077 > > < $var_exprs = > > preg_grep('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+(?:\((?:' . > > $this->_qstr_regexp . ')*\))?))*(?>\|@?\w+(:(?>' . > > $this->_qstr_regexp . > > '|[^|]+))*)*$!', $tokens); > > --- > > > $var_exprs = > > preg_grep('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+(?:\((?:' . > > $this->_qstr_regexp . > > > > ')*(\s*,\s*(?:'.$this->_qstr_regexp.')*)*\))?))*(?>\|@?\w+(:(?>' . > > $this->_qstr_regexp . '|[^|]+))*)*$!', $tokens); > > 1131,1132c1131,1132 > > < > > < preg_match_all('!\[(?:\$\w+|\w+(\.\w+)?)\]|(->|\.)\$?\w+(?:\((?:' . > > $this->_qstr_regexp . ')*\))?|^\w+!', $var_ref, $match); > > --- > > > > > > preg_match_all('!\[(?:\$\w+|\w+(\.\w+)?)\]|(->|\.)\$?\w+(?:\((?:' . > > $this->_qstr_regexp . ')*(\s*,\s*(?:'.$this->_qstr_regexp.')*)*\))?|^\w+!', > > $var_ref, $match); > > > > > > --------------------------------------------------------- > > > > I've just added (\s*,\s*(?:'.$this->_qstr_regexp.')*)* to allow multiple > > parameters. At this time > > no blanks are allowed between the parameters and the comma or it will result > > in a Smarty error > > (because Smarty interprets it as a Smarty function parameter {func param=1} > > and not as a > > method parameter). > > Now my application is working again. Woohoo! > > > > The only thing which I still would like to have are thing like NULL, TRUE > > and FALSE as parameters. > > Then you could do something like {$foo->bar(null,'blah')} which doesn't work > > right now. Even > > {$foo->bar(true)} isn't interpreted correctly. > > > > Perhaps the best thing would be a recursion for each specified parameter if > > an object's method is called. > > Then you could even use a syntax like {$foo->foo_it($bar->bar_it(true))} > > which looks a bit complex > > but is really usefull sometimes ;-) I'll try to implement this ... > > > > André > > > > > > > > > > > > > > > > "Monte Ohrt" <monte@ispi.net> schrieb im Newsbeitrag > > news:1040068296.11922.76.camel@lena.ispi.prv... > > > I committed to CVS, this syntax is now allowed: > > > > > > {$foo->bar('blah')} > > > {include file=$foo->bar('blah')} > > > {include file=$foo->bar->bar2->bar3->bar4('blah')} > > > > > > You can also embed template vars: > > > > > > {$foo->bar("you $foo")} > > > {include file=$foo->bar("this is $my var")} > > > > > > Please help test this, it affects many core components. > > > > > > Monte > > > > > > > -- > Monte Ohrt <monte@ispi.net> >

« previous php.smarty.dev (#428) next »