Re: [SMARTY-DEV] Re: Smarty and object support
| From: | Monte Ohrt | 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>