Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:87013 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 707 invoked from network); 3 Jul 2015 23:05:39 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jul 2015 23:05:39 -0000 Authentication-Results: pb1.pair.com smtp.mail=smalyshev@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=smalyshev@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.192.179 as permitted sender) X-PHP-List-Original-Sender: smalyshev@gmail.com X-Host-Fingerprint: 209.85.192.179 mail-pd0-f179.google.com Received: from [209.85.192.179] ([209.85.192.179:33667] helo=mail-pd0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 0C/80-18768-34517955 for ; Fri, 03 Jul 2015 19:05:39 -0400 Received: by pdjd13 with SMTP id d13so69876133pdj.0 for ; Fri, 03 Jul 2015 16:05:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=/4ARlTytP2UPkMw315yFFuYOVfmPK2z7+PsScn4yG8E=; b=CYueSOj8/BEAPV8Yi1EIWjZhl3MsZiZ+mU4SnxXF1qfrwM4T3PYp9CGrjZbXe9puBE V6/39GIKfxIZtC09h4xSU7+deGS0O7G68N3FaOLZ+anRf85eAE4uJRJmhGvGU+4OK4Sc P+DfG2oF39otzVOBLXrKXQ/12T2fUeAzthnzQiYoeONFjorInmG0HRyYzPtH6s2QZrWn 6McZiL8KZz3FuEGiSHlN/izNcD7Q+fqknpOLQy6BE4YqPje/81PKdgRORFMx1akSSB/L UjnynANUva8Hf42Rzf/9liQhW+/e+5c1y9q6W8FfH6a0rE02r1d0KGag56iBcid6GiPO w40Q== X-Received: by 10.69.0.8 with SMTP id au8mr81647950pbd.112.1435964736352; Fri, 03 Jul 2015 16:05:36 -0700 (PDT) Received: from Stas-Air.local (108-66-6-48.lightspeed.sntcca.sbcglobal.net. [108.66.6.48]) by mx.google.com with ESMTPSA id kr8sm10163838pdb.86.2015.07.03.16.05.34 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 03 Jul 2015 16:05:35 -0700 (PDT) Message-ID: <55971538.5020505@gmail.com> Date: Fri, 03 Jul 2015 16:05:28 -0700 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Nikita Popov , =?UTF-8?B?Sm9oYW5uZXMgU2NobMO8dGU=?= =?UTF-8?B?cg==?= CC: PHP internals , Dmitry Stogov References: <1435240516.15676.7.camel@kuechenschabe> In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] Allow exceptions in __toString() From: smalyshev@gmail.com (Stanislav Malyshev) Hi! > a) Error handlers can (and often do) throw. E.g. it is possible to convert > the two recoverable fatal errors that __toString() currently throws into > exceptions and end up in the situation you describe, only with even less > safety and more leaks. However this applies to all occurrences of > zend_error or php_error_docref that generate a non-fatal error. From a > quick grep I estimate we have about 4000 places in the codebase where this > can occur and I'm sure many of them do not check for EG(exception) > immediately after throwing the error. > > b) Destructors can throw. We have approximately 2500 places in php-src > destroying a zval, which could potentially throw. I don't think I've ever > seen an EG(exception) check after a zval_ptr_dtor(). You don't usually use the value being destroyed after zval_ptr_dtor(). You could, however, use the value that was supposed to be converted after __toString, and you probably are if you're converting it. The problem is not that exception is thrown, the problem is that the code assumes there's some workable value and there's none or at least not the value it expected. With error handlers, it is trickier but the code that produces the error usually does not expect everything to be fine after the error handler is done - on the contrary, it explicitly expects it *not* to be fine, since it just reported that something is not fine by invoking the error handler! Of course, we have there all kinds of issues with error handlers messing with the environment, but it's much harder to cause this problem by accident. The problem, as I see it, is not the throwing of exception by itself, but the fact that the code assumes the defined state of the variable being converted, but when exception is thrown, we don't get that state, but we also don't know something bad happened. Of course, we could do something like set the value to empty string, but since again there's no check there the code would just assume we've got legitimate conversion to empty string - which is not the same as "we've got error" and could lead to very unexpected consequences (such as somebody erroneously supplying object as a password and system treating it as empty password). > If you want to protect against side-effects after exceptions in critical > places like database interaction, we can introduce exception checks right > before the operation is executed and prevent anything bad from happening I don't see how this is possible - we have no idea which places can be "critical" - any interaction with now-undefined variable could lead to a disaster downstream. -- Stas Malyshev smalyshev@gmail.com