-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mark a function as escaped #68
Comments
Seems like something to consider for Thoughts @barryvdh Good idea, and best way you think to implement it? An option might be to have something like: $functions = [
'nav_link' => [
'safe' => true
]
] |
Right now, the HelperLoader accepts closures and strings, which are then converted to Twig_SimpleFunction objects. But it could easily be changed to simply also allow Twig_SimpleFunction:
Then you can just pass a Twig_SimpleFunction in the config, with the options array as third parameter.
(Twig_Function_Function is deprecated since 1.12 and to be removed in 2.0) |
I'm looking at this now. My intention is to support the following ways to load a function through the config file: 'functions' => [
'secure_url',
'link_to' => [
'is_safe' => ['html'],
],
new Twig_Function_Function($name, $options),
new Twig_SimpleFunction($name, $callable, $options),
] |
As proposed in rcrowe/TwigBridge#68 Allows Twig_SimpleFilter/Function, or an array with either just the options, or a callback. Without callback, is just calls that function. 'link_to' => array( 'is_safe' => array('html') ), 'custom_function' => array( 'is_safe' => array('html'), 'callback' => function(){ return '..'; } ),
Any word on this? All the form helpers ( |
If you want you can take a look at how I've done this now in the extensions in https://github.com/barryvdh/laravel-twigbridge |
Oh and you could set autoescape to false just for your form. http://twig.sensiolabs.org/doc/tags/autoescape.html |
@barryvdh You're saying this will work out of the box with your version of TwigBridge? Giving this a whirl now... thanks! A couple things off the bat:
|
I would really like to see this too. Being able to mark a function or alias as safe would save me from writing |
I would also like a way to indicate that the Laravel form helpers are fine to not escape, without writing raw constantly. |
@glennjacobs @rickywiens See my fork.
You can write Also see this thread. Hasn't been thoroughly tested yet. Hoping @rcrowe or @barryvdh will reincorporate my changes. |
Looks good, hoping it gets incorporated! |
It function escaping/marking as safe already is incorporated in my twig bridge: https://github.com/barryvdh/laravel-twigbridge |
I'll get this into the 0.6 branch today. I'm |
I'm pretty busy today, but you can look at https://github.com/barryvdh/laravel-twigbridge/blob/master/src/Barryvdh/TwigBridge/Extension/HelperExtension.php
|
So this is working in 0.6 now, thanks @barryvdh & @mnbayazit for the work on this. The config is a mess while I was testing some things, mainly as a note until I update docs / comments. I would prefer not to mark the whole Facade as |
@rcrowe You don't have to mark the whole Facade as safe. Take a look at the method. Instead of
You can write
To flag specific methods as safe via a regex, or list them out explicitly:
That's the best I could come up with. @barryvdh It doesn't break chaining per-se, but it only goes one level deep. Methods will only be marked as safe if they return a string. If they return an object which contains a method that returns a string and you call that sub-method, it won't be escaped. I couldn't figure out a nice way to get around that. The solution you offered up as is OK but it gives up the ability to be explicit about which functions are escaped. |
@mnbayazit I've taken the code (minus the regex stuff for now) from your fork so facades support:
So I was going to list methods. Just wondered peoples opinions on doing so. There might have been questions about keeping it updated etc. |
@rcrowe Indeed. I was hoping the regex solution would help catch future functions, but it's not ideal -- it could pick up functions you don't want as well. Another solution I thought of was to disallow calling the function at all unless it's explicitly listed. This forces the consumer to make a decision about whether or not it's safe. Actually, better would be to throw an error that tells them they need to add it to the config so that they're not confused when it's missing. |
I think of would actually be better to create extensions for the functions
|
Yep, I think I agree. If you've gone to all that effort of setting an array of method / options, then you might as well keep an extension up to date. Also brings extra flexibility. I'll keep the existing loader extensions for user options. |
@barryvdh In the event that it's not a string but has a I don't like having to write my own facades for functionality that already exists and is expected to exist from the Laravel docs. They would just be calls into the existing facades anyway; serves almost no purpose IMO. I haven't used Laravel extensively yet so I don't know how much of a problem maintaining this config would be. Blade doesn't have automatic escaping does it? You have to be explicit about everything? So there's nothing we can hook into... @barryvdh You wrote the IDE-helper... could we maybe leverage that to create stubs for all the existing facades -- a new facade that makes a call into the existing facade -- and then we can go through each method by hand and mark them as safe or not? How would we do this though? Functions are listed out in the config, but we don't have any way to annotate methods; PHP doesn't support decorators or attributes. Instead of |
I wrote extensions for the most common functions in my package, like form That syntax would add a Twig function class_function, whichs executes
|
You could chain the Facade calls actually, by extending Twig_Markup and using that in the Facade caller, something like this:
But I haven't really found how you can chain a safe Twig_SimpleFunction |
I was in the process of moving Laravel facades, filters & functions to their own extensions when I came across an issue with the facade extension clashing with variables passed in through View::make(...). But this can also happen with Laravel functions & filters. All a user has to do is pass in the following & the Config facade will break: array(
'Config' => 'foobar'
) I wondered peoples thoughts on a couple of syntax ideas for the facades:
FYI - Marking functions as safe has been completed. |
You mean you want to move all the facades into a namespace? I'm not a fan of this idea. Let users choose the name they want to import the facade as, and it's their fault if they create a clash. View variables should trump global variables anyway. |
The first example can already be done for most of the call, by using the global app variable. But you have to call the binding instead of the facade. |
Yep, agree namespacing is crap. As it stands all facades, functions & filters are in the config file. You can add, remove & edit as much as you want. @barryvdh had talked about moving to their own extensions, so I was just bringing up the issue of not being able to edit the name say & clashes arising. I would have liked to separate out user & laravel extensions, thoughts @barryvdh ? |
I'm not sure. I think when you provide extensions for the helper functions (asset/action/trans etc) and namespace the functions to their class/facade (form__, str__ config__, session__, url_* etc), it should be clear enough. |
Re-publish the TwigBridge config file. Our extensions now handle this. Just need to decide on which functions / filters should be escaped. Thoughts? |
You mean which of the "default" functions need to be escaped? Is there a list we can reference? The obvious answer is that anything that generates HTML should be marked as safe, everything else should be escaped. |
Right now, marked as safe are:
Not safe:
What to do?
So I think Str should be changed, but the rest is fine? Or should the functions that don't generate html, not be marked safe? (Like Trans, Config and csrf_token) |
You can also look at this for examples: https://github.com/symfony/TwigBridge/blob/master/Extension/ |
I don't think trans should be safe, you could be using placeholders like Hello :name and name would be coming from a user input. Sent from my iPhone
|
Good point. |
And for filters, there also is pre_escape (http://twig.sensiolabs.org/doc/advanced.html#automatic-escaping), so trans/str could still be safe, but only when used as a filter, because we can encode the input itself. |
See #68, added filters for trans, with pre_escape
@barryvdh What would be the disadvantage of making something like Config and URL not safe? I think you're thinking about this backwards. Safety should be the default, therefore anything that has the slightest chance of spitting out HTML needs to be escaped automatically. If this behaviour isn't desired for some special case we can always override it with URLs, for example, can contain single-quotes apparently which would cause your page to break if you tried writing Escaping |
I'm not really sure about the urls. |
In some sense, sure, but I don't want to have to think "did I put any quotes or ampersands or anything weird in any of my config settings?" every time I output something. Not that I think there's ever a need to be echoing config settings to the browser, but you might want to do it once in awhile for debugging or I don't know what, but flagging it as safe when it could possibly not be seems more detrimental than helpful. |
My first thought was that However, after thinking it through, the rare cases where you need to output an unsafe config variable, it seems fair to have to use the raw filter. I've removed |
Yes agreed, when we don't know for sure, better use a safe default :) |
Just tagged |
It would be nice if there was a way to mark a function as escaped in the configuration, rather than appending
|raw
throughout templates. It seems that the Twig way to do this is:It seems that a way to do this could be allowing
config.functions
to acceptTwig_Function_Function
instances?The text was updated successfully, but these errors were encountered: