Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106916 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 48494 invoked from network); 9 Sep 2019 11:52:14 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 9 Sep 2019 11:52:14 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id 37BD82D2031 for ; Mon, 9 Sep 2019 02:27:20 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp3.php.net X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,HTML_MESSAGE, RCVD_IN_DNSWL_MED,SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS3215 2.0.0.0/16 X-Spam-Virus: No Received: from mail.sensational.ch (mail.sensational.ch [IPv6:2001:8a8:6004:0:dead:beef:0:1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp3.php.net (Postfix) with ESMTPS for ; Mon, 9 Sep 2019 02:27:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=2VZQH+Ib69IZuNB1LkGDQ2ibg2J8DVEPCVBG4Ckh9GQ=; b=QVM2pyc9xRCYrr6qCdOLxT+cOzo/e/7nHr/bC4Qu7CHSVLg9t45LBZpwpaWkzmIbF7 PZtfcqjc+rsqxaP1UTeciSm3mZcv5NwxzxBDJP1E1OHaM0JiuYCNHHuXJYq6kcJAOMoR t/nbOwr+8ZxxxJauQp3BSmg1weTeq0rKWT3TPn6ym9WV4GrZejALSR0RNf07NBKrVaLW nIS+QIu3aeP+e6oDMTcyZVzS2g14xpBQLBOUS0JpB6I6lo1yQl/NYp4DOmx260izHcPG 5dxMbVy1ASWBP/8oYgjy+rLtZ3IiKQ03YAex8Kur/Af3ew5luZdGlqJLMM2h43gBAJpJ yUNA== X-Gm-Message-State: APjAAAXoz8tj6mktB7lUI7AGlHnj3rppeDY/lcF3naPGRdBDVAXmy4nc mY1xckk1Oo6VD6e2HRH4zaB0zNYMjAloKppGUjr3bPWERtuCyjg8J790oeEwlTP51WeNXpOiTYK 4o30wLXUQNGuGfLDptpz1qJcR0Sj93kQN7s1eD4stVaTT X-Received: by 2002:a5d:6b0f:: with SMTP id v15mr16664859wrw.19.1568021237147; Mon, 09 Sep 2019 02:27:17 -0700 (PDT) X-Google-Smtp-Source: APXvYqyxbQ9TnQJFNg4eCNJfV404ybJsUJFoQdKwPKY9N6bcyNwVrOSkYpHwrisN0vtlAOIcY3F/vf7lT9YBjF9QsyI= X-Received: by 2002:a5d:6b0f:: with SMTP id v15mr16664840wrw.19.1568021236917; Mon, 09 Sep 2019 02:27:16 -0700 (PDT) MIME-Version: 1.0 References: <4af5ebe3-d88a-925d-66dc-9159912ece81@gmail.com> In-Reply-To: <4af5ebe3-d88a-925d-66dc-9159912ece81@gmail.com> Date: Mon, 9 Sep 2019 11:27:06 +0200 Message-ID: To: Stanislav Malyshev Cc: PHP internals Content-Type: multipart/alternative; boundary="000000000000d3bb8f05921b645a" X-SA-Do-Not-Run: Yes X-Envelope-From: Subject: Re: [PHP-DEV] FFI extension / NULL-Checks From: phofstetter@sensational.ch (Philip Hofstetter) --000000000000d3bb8f05921b645a Content-Type: text/plain; charset="UTF-8" On Mon, Sep 9, 2019 at 10:13 AM Stanislav Malyshev wrote: > > isset($err) > > $err[0] != null > > -> is always true, regardless of whether func as assigned an error or not > > > > $err[0]; > > -> segfault > > This is a bit confusing - if $err[0] segfaults, how it can be != null? > Does this behave differently in different contexts? Anyway, it shouldn't > probably segfault in any case, so this looks like a bug. > I think there are a few disconnected issues. One is that checking something for being NULL is a bit tricky with the given API and the other is that the API around FFI\CData is a bit inconsistent and tricky to use. Given $err = $ffi->new("Error*"); what the library does is assume that $err is now a pointer to an array (which is what C does I guess), but yet, there seems to be a bit of an issue with actually accessing that array (if it's set to NULL) - and also, don't use var_dump() to inspect it - that's deceptive because there's a debug_info handler that knows ore than the actual field accessors (which too makes this more complicated than needed). So. Let's assume that in $err = $ffi->new("Error*"); $ffi->func(FFI::addr($err)); func() sets that argument to NULL, then $f = $err[0]; var_dump(gettype($f)); returns "object" - so the zeroth index exists (hence the isset being true). However there's also $f = $err->{0}; which normally would throw "Attempt to read undefined field '0' of C struct/union" but because $err is seen as an array, accessing a property named 0 is possible, but then a second null check will happen via https://github.com/php/php-src/blob/09e9c4f3c11a875c67334578621084f156155307/ext/ffi/ffi.c#L1103-L1107 and you get "NULL pointer dereference" instead. I believe this difference between [0] and {0} shouldn't exist. And even aside of that, I see no way in which user-code can ever check any reference for NULL because any access of a Cdata property or index that's happen to be set to NULL will either segfault, throw or fail a comparison in PHP because Cdata instances, according to PHP's type conversion rules, always convert to something that compares truthy when put in boolean context. The inconsistency between [] and {} aside, I believe there should be an FFI::isNull() static method or a Cdata::isNull() instance method that allow user-code to check things for being NULL. Or the throw in the code I liked to above is removed, but that would leave the inconsistency between [] and {} Or maybe I'm just overlooking something and there's a simple way to check something for being NULL, but if there is, it IMHO needs better docs. Philip --000000000000d3bb8f05921b645a--