Re: [SMARTY-DEV] Re: Smarty and object support
| From: | Andr� Rabold | 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>
>