Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:117391 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 70815 invoked from network); 21 Mar 2022 13:57:53 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 21 Mar 2022 13:57:53 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0B73D1804D9 for ; Mon, 21 Mar 2022 08:24:09 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: **** X-Spam-Status: No, score=4.0 required=5.0 tests=BAYES_50, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_SOFTFAIL, T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-oo1-f52.google.com (mail-oo1-f52.google.com [209.85.161.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 21 Mar 2022 08:24:08 -0700 (PDT) Received: by mail-oo1-f52.google.com with SMTP id p10-20020a056820044a00b00320d7d4af22so19549191oou.4 for ; Mon, 21 Mar 2022 08:24:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=EbEN6ZmpN8avvsyhFliQzzjvf3E+/msgCDqkd5TAiJM=; b=4BPMtYfjr0RDbabUgKDAPNCvEPDP6JeeV0NCWLu8f0GMMxq3YbOvRQFo5snmpZQLHi P+vyBXYyAVziqVrPwdVghtzITK+Kffi4SGvG4JruynkkZsbgP4s3UHriNViJqWJjr6/7 1LXLYdNRknjiS5hlpazF5oRzv+jGkIuLm9f6jsn5eEKRiRMSRepvAUoC2xh2h94iM/NF 03dCytRoGbKAp6QkONGbWUvcU0PyOhsZCbkyupouC82hgDSIbFDwXpgWV5utkpSoQocm QeJIRHLDFf/Kx7+6hPm0Ew6VvmRqmkB4db0/pUlNzOEhQZI+2cDMFOuPcu94TGmD5W9O F5ow== X-Gm-Message-State: AOAM5324Twi4WIgha3o3TZjV71qnTm3D6cyZN/LOpXU6fiMw8f4E9uCF OcoS7PrgZVvjXCpze4m0/ugY7bllq/ZhgO/XKcMANNRDK7BxNQ== X-Google-Smtp-Source: ABdhPJy67TYjE7RuuFT39troYZubqU/DucEYDOyAVntZzmmB++RMhXS0L696x4b/8FMIsA02L4y/RLKxrAVxF3FNuu8= X-Received: by 2002:a05:6870:248c:b0:d7:19f3:a52c with SMTP id s12-20020a056870248c00b000d719f3a52cmr7889563oaq.149.1647876247663; Mon, 21 Mar 2022 08:24:07 -0700 (PDT) MIME-Version: 1.0 Date: Mon, 21 Mar 2022 10:23:56 -0500 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="00000000000060462505dabc16d5" Subject: Discussion: String streams From: pollita@php.net (Sara Golemon) --00000000000060462505dabc16d5 Content-Type: text/plain; charset="UTF-8" TL;DR - Yeah, PHP, but what if C++? Feel free to tell me I'm wrong and should feel bad. THIS IS ONLY IDLE MUSINGS. I was reading the arbitrary string interpolation thread (which I have mixed feelings on, but am generally okay with), and it got me thinking about motivations for it and other ways we might address that. I spend most of my time in C++ these days and that's going to show in this proposal, and the answer is probably "PHP isn't C++" and that's fine, but I want you to read to the end, because XSS is perennially on my mind and this might be one extra tool, maybe. PHP internal classes have the ability to handle operator overloads, and one use for overloads I quite like from C++ is streaming interfaces. Imagine the following: // Don't get hung up on the name, we're a long way from bikeshedding yet. $foo = (new \ostringstream) << "Your query returned " << $result->count() << " rows. The first row has ID: " >> $result->peekRow()['id']; At each << operator, the RHS is "shifted" into the string builder, and the object instance is returned. At the end $foo, is still that object, but when it's echoed or cast to string it becomes the entire combined string. As implementation details, we could keep the string as a list of segments or materialize completely, that could also be optimized to not materialize if we're in an output context since the intermediate complete string is unnecessary. Don't worry about this for now though. That by itself is... curious as an option, but not terribly interesting as we DO have proper interpolation and it works just fine, right? The reason I'm bothering to introduce this is that we could also build contextual awareness into this. During instantiation we could identify the context like: $forOuput = new \ostringstream\html << "You entered: " << $_POST['textarea']; $forURIs = new \stringstream\uri << BASE_URI << '?'' foreach ($_GET as $k => $v) { $forURIs << $k '=' $v << '&'; } These specializations could perform automatic sanitization during the materialization phase, this could even be customizable: $custom = new \ostringstream\user( landonize(...) ); We wouldn't be giving arbitrary operator overloading to the user, only arbitrary sanitization. Alternatively (or in addition), the point of materialization could be where we make this decision: echo $stream->html(); ------ I'd build this in userspace, but of course we don't have operator overloading, so the API would be a somewhat uglier function call: $stream->append("This feels ")->append(FEELING::Sad); Maybe the right answer is open the door on user-defined operator overloads, but my flame retardant suit is in the shop and I don't really need to open that mixed metaphor. -Sara --00000000000060462505dabc16d5--