php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69379 zend_parse_parameters and reference, flag is reversed
Submitted: 2015-04-05 15:07 UTC Modified: 2015-04-06 14:54 UTC
From: danack@php.net Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: master-Git-2015-04-05 (Git) OS: N/A
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: danack@php.net
New email:
PHP Version: OS:

 

 [2015-04-05 15:07 UTC] danack@php.net
Description:
------------
It seems that in PHP7 the '/' flag has had it's meaning reversed. It is documented as:

"'/' - This indicates that the preceding parameter should be separated from the calling parameter, in case you wish to modify it locally in the function without modifying the original calling parameter."

i.e. if you want a function to accept a parameter by reference you should _not_ use this flag, so that when you set the variable inside the function, the new value is seen outside by any reference to the variable outside the function.


However it is now _required_ to set the '/' flag to pass a variable by reference.


Example code from - https://github.com/mkoppanen/imagick/blob/phpseven/imagick_class.c#L11636


This code works to set the parameter in 5.x:

zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|zz", &reference_obj, php_imagick_sc_entry, &z_best_match_offset, &z_similarity);
if (z_similarity) {
    ZVAL_DOUBLE(z_similarity, similarity);
}

That code needs to be changed to this in 7:
zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|z/z/", &reference_obj, php_imagick_sc_entry, &z_best_match_offset, &z_similarity);
if (z_similarity) {
    ZVAL_DOUBLE(z_similarity, similarity);
}

It appears this change was done in this commit:
https://github.com/php/php-src/commit/c1965f58d4dd3970912dcd6a63ccd5860bae1a97



Test script:
---------------
<?php

$imagick = new \Imagick();
$imagick->newPseudoImage(640, 480, "magick:logo");
$imagick2 = clone $imagick;
$imagick2->cropimage(40, 40, 250, 110);
$imagick2->vignetteimage(0, 1, 3, 3);

$similarity = 'not set';
$bestMatch = 'not set';
$comparison = $imagick->subImageMatch($imagick2, $bestMatch, $similarity);

var_dump($similarity);

Expected result:
----------------
float(0.90996121310752)

Actual result:
--------------
string(7) "not set"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-04-05 15:15 UTC] nikic@php.net
"/" means "separate" and indeed in PHP 7 it is required in all cases where you want to modify a passed zval, even if it's a reference. But I'm not sure I get what the bug report is about, is this a documentation problem? If so, could you please point to which docs you're quoting here?
 [2015-04-05 15:25 UTC] danack@php.net
I guess it is documented in the upgrading guide - https://wiki.php.net/phpng-upgrading

"arguments passed by reference should be assigned into the referenced value. It's possible to separte such arguments, to get referenced value at first place."

So that really means, if your function wants to accept a parameter by reference it must change from 'z' to 'z/' ?
 [2015-04-06 14:54 UTC] danack@php.net
-Status: Open +Status: Not a bug
 [2015-04-06 14:54 UTC] danack@php.net
Ok, apparently this isn't going to change back due to the other changes in how references are handled. It could still do with being better described in the upgrading manual imo.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 19 16:01:31 2024 UTC