Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:94629 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 86687 invoked from network); 22 Jul 2016 12:41:55 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 22 Jul 2016 12:41:55 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.44 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.44 mail-wm0-f44.google.com Received: from [74.125.82.44] ([74.125.82.44:36487] helo=mail-wm0-f44.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 40/E2-52781-29412975 for ; Fri, 22 Jul 2016 08:41:55 -0400 Received: by mail-wm0-f44.google.com with SMTP id q128so55881457wma.1 for ; Fri, 22 Jul 2016 05:41:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding; bh=3yrv/fSZ1jKdcBHrZxJsKJulBSosSyFRaAA5FvO7Uxk=; b=WDzMXM1sN1GwXGvh/eo+CXN33pDGcD+1DAO+0A7bZ++4hqMmDd/RIK4+3Y/9Yua3/f 9o8g1VZICE0py3P+0q9AEgBOvBMlvq/2XtSXVp5B4C2Z8cExlVGIwjFtDu7P8HNcmQ4P PL+Ntznr4FyFIf9LUUUYkqC5i/1uKOt84hSsXnq3XzC+qlDUdb2wvTTro2Vxq8idFK7d hLUuRwTwgqrMjg1cqMU4I9JyJZ3hoKtkxazLAL3QG8QAaMMbmPXbt6Rxxkp2GokjeNsO 8gFeUSpGLT/gDRlwOQRKe52U/TjqmKoO7j+zjQuf/Fxp/hy0tV/LF9XBbeNFxHDzpfMj xhDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding; bh=3yrv/fSZ1jKdcBHrZxJsKJulBSosSyFRaAA5FvO7Uxk=; b=B0T2ZRGBUdrS/mjzydYlpFEBMuT/ki/vu1ex0WwuxbCaBgeTcQLCP0mqWKMsvap28c 3sPsAANxvB8xUTzF6vO3oHLfO8Ult5p5R/tR6/nTR3aBmQ2lmxM4uYfyx83n7fmO0JV4 zVV4zQVI0S+7IbPS+rQBsOEEeab4sNAPtOBLhIp8TQGxPyck1mdorpxcNFGgxcDXzUd8 RSHh+E6t0IQpqXaGF7+AYdDl2hDejE0ci7TPXsOS/KUsPSanDO5dm2VTTJd5GEf/vG0i LZezjWenJljDOnMG0P1x94F7muITds0RLugcS5Ioybhiq5onelHQNK6dxBWQwkajiFgr GbEw== X-Gm-Message-State: ALyK8tIcx3i1U1ndv/fk8x5rC1HF+FY5R8hMhy2yU0aRzWFRG6hIkGnMj04A1yrgHUtV1w== X-Received: by 10.28.38.196 with SMTP id m187mr24245040wmm.81.1469191311358; Fri, 22 Jul 2016 05:41:51 -0700 (PDT) Received: from [192.168.0.98] ([93.188.182.58]) by smtp.gmail.com with ESMTPSA id d62sm12448673wmd.7.2016.07.22.05.41.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 22 Jul 2016 05:41:50 -0700 (PDT) To: internals@lists.php.net References: <8a39df34-4a23-c496-15f6-20a62d27fc59@gmail.com> Message-ID: <5f9e10f3-b343-bce7-5d94-6b40e881efa9@gmail.com> Date: Fri, 22 Jul 2016 13:40:10 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] [RFC] New operator for context-dependent escaping From: rowan.collins@gmail.com (Rowan Collins) On 22/07/2016 08:31, Michael Vostrikov wrote: >> sticking the escaping types after the output makes it hard to spot what's > going on with anything other than a simple variable. e.g. $this->renderView($thing->getViewName(), 'html'), 'js' ?> > > In Twig escapers and filters are also written after a variable, and this is > not confusing for many users. > {{ render(thing.viewName, 'html') | escape('js') | somefilter }} Sure, but in Twig, Smarty, etc filters aren't just a special syntax for doing escaping, they're a fundamental part of the language. In essence, they're just a different way of writing a function call, a bit like Sara's pipe operator, which incidentally would allow this: viewName, 'html') |> escape($$, 'js') |> somefilter($$) ?> >> Because it's not obviously part of the the escape parameter can be used elsewhere: 'oops', 'html' ?> Operators don't normally have a list of > arguments. > > Just a default variable, nothing complicated. > If they write echo like this, they will notice 'oopshtml' and then correct > this contstruction. > Binary operators have 2 arguments (add($a, $b), escape($string, $context)), > 'for' has 3 arguments. Binary operators have a left-hand operand and a right-hand operand; unary operators have an operand immediately before or immediately after their symbol. You don't write +$a, $b you write $a + $b. The only exception is the ternary decision operator, $a ? $b : $c, which still doesn't use a comma. Functions, on the other hand, have a name, and a pair of brackets. So +($a, $b) looks a bit like a function call with a funky name; that would give us . I can see your logic in defining it this way, it just doesn't look like anything else in the language, and that's a bad thing for people using it properly. >> And this is the reason why I want it to be a call of function with constant >> name. This is very clear - turns into >> some_escape_function($str, $context). The more you compare it to a function call, the less I understand how it gains over just defining a function e() and writing >> What happens if you mistype the argument? Or with the > current proposal's use of '|', what if you get that syntax wrong? 'html || js' *?> > > Exception: Unknown context 'hmtl'. > Exception: Unknown context ''. > Exception: Unknown context 'html, js'. > > If the handlers for these contexts are not set, of course. But if these are run-time errors, how is the clever syntax helping people get it right here? If you can pass a variable as the escaping method, define arbitrary escaping functions, etc, you can't even write a strict static analyser. >> if you're mentioning the whole function name, you can just call it already >> > Do you mean the function autoloading? What is the difference with not-fq > name 'PHPEscaper' then?) And how to use an escaper like [$this, 'html'] ? You've merged two unrelated lines from my e-mail here, so I'm not sure what your question is. By the first line, I meant that if you write "" you might as well just write "html($foo) ?>". The syntax has gained you nothing but a minimum version of PHP and some head-scratching from new users. >> JS escape only; not sure if this should encode as JSON, or just a JS safe > string; maybe as well / instead... > This looks unclear for me - why I cannot use json for strings and what if > my variable sometimes is an array, sometimes a string? 'foo' is valid JSON - there is much hot air about the difference between a "JSON value", a "JSON document", etc, but long story short, it is perfectly fine to say On the other hand, if I have an array and ask for it to be HTML-escaped, nothing iterates the array for me, it will just print "Array". So if I ask for it to be "JS-escaped", why should it magically produce a JSON array? Not to mention the fact that PHP "arrays" cannot be losslessly represented as either an object or an array in JS (they have both arbitrary keys and well-defined order, JS makes you choose one or the other). >> The biggest use case for this is people who *aren't* using a framework > ... so customising the definitions is going to be the exception, not the > rule > They can setup their escapers once, this is not a problem, but the problem > is e.g. default flags for html escaping. > Customization is required. Customizability is required, yes, but it absolutely should not be mandatory. If people are using a framework already, *they will already have a method of doing this*. This feature is really only useful for people who are relying on absolutely minimum framework code, who want something to work "out of the box". If I have to write "register_escape_handler(function($string, $mode='html') { .... })" I might as well just write "function e($string, $mode='html') { .... }". There's not even a question of autoloading, because nothing is going to autoload the procedural code that runs "register_escape_handler" anyway. >> If we make it too flexible, we're basically inventing a new templating > language > We cannot forbid a customization, so any custom escaper is a kind of new > templating language. > The operator must be simple for use. If someone wants to create new > templating language in his application, let he create. It will be in > application, not in PHP. I think we're in agreement here - simplicity is key. :) >> The trick with the magic class name and namespace aliasing is neat, but > feels likely to confuse a lot of users > > Yes, I have to agree. Maybe more better way is to make it similar to > set_error_handler() - not for context as it is in RFC, but for 'escape' > callable. Personally, I think having a separate handler registered for each context argument, like streams, makes more sense. I don't see the use case for customising how contexts are combined, passing variable contexts around, or anything else that is gained by one callback with two parameters. Again, focusing on simplicity: becomes: And, as I say, the common escape handlers should be defined by default, just like a whole bunch of stream types are. Regards, -- Rowan Collins [IMSoP]