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

From: Date: Tue, 17 Dec 2002 17:46:18 +0000
Subject: Re: [SMARTY-DEV] Re: Smarty and object support
References: 1 2 3 4  Groups: php.smarty.dev 
Request: Send a blank email to php-smarty-dev+get-429@lists.php.net to get a copy of this message
On Tue, 2002-12-17 at 11:08, André Rabold wrote: > 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} The problem is you are crossing the line of keeping application logic out of the templates. You really should do something like this: {if $user_is_authorized} ... {/if} ie., let the _application_ deal with constants, calling isAuthorized object, etc. etc, and just assign a simple boolean value for the template. This way you have complete control over the application logic _outside_ the template, and the template syntax is kept clean and concise. I'm currently reorganizing the regular expression work in Smarty_Compiler, it is getting a bit out of hand. I'll let you know when that is committed. Monte > > 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> > > -- Monte Ohrt <monte@ispi.net>

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