Ticket #323 (closed defect: fixed)

Opened 10 years ago

Last modified 10 years ago

[PHP MapScript] Problem with class parameters always assigned by reference

Reported by: dmorissette Owned by: dmorissette
Priority: highest Milestone:
Component: MapScript-PHP Version: 4.0
Severity: normal Keywords:
Cc: sfournier@…

Description

(This problem comes from CWC bug 2030)

When drawing the scalebar (for instance), the output is forced to PNG, before
drawing the scalebar php code save the old image type, set it to PNG the draw
the scalebar. After all theese steps, the old image type is restored. the code
looks like this:

$szOldImgType = $map->outputformat->name;
$map->selectOutputFormat("PNG");
$map->drawScaleBar();
$map->selectOutputFormat($szOldImgType);

The previous code won't work unless the first line is:

$szOldImgType = $map->outputformat->name."";


I just saw that a lots of mapobject (probably others) attributes are not copied
when using the "=" operator, but referenced.

Is there anything we can do to prevent PHP MapScript from behaving like this?

Change History

Changed 10 years ago by dmorissette

Perhaps calling zval_dtor() before resetting a class member value in 
php_mapscript.c could help ... the destructor would force the references to be 
lost and then resetting the member to a new value would force the creation of a 
new PHP ZVAL for the new value... hopefully the side-effect that we experience 
here wouldn't happen any more.

Changed 10 years ago by dmorissette

  • priority changed from high to highest
Raising to P1, we must fix this before the release ... note that this happens 
with all class members in PHP MapScript and not just the output format

We should check the reference count in the IF_SET_...() macros, and if it's 
greater than 1 then call zval_dtor() before resetting the member variable 
values.

Changed 10 years ago by dmorissette

  • status changed from new to assigned
Working on this now.

Changed 10 years ago by dmorissette

  • status changed from assigned to closed
  • resolution set to fixed
Fixed.  We had to call the following when setting an object property in 
php_mapscript_util.c:

   SEPARATE_ZVAL(phandle);
   zval_dtor(*phandle);
   ZVAL_STRING(*phandle, szNewValue, 1);

(or ZVAL_LONG() or ZVAL_DOUBLE() depending on member type).

I'll attach below the script that I used to test this on various mapscript class 
member types.

---------------

<HTML>
<PRE>
<?php

//
// Load MapScript module.
//
  dl("php_mapscript_40.so");

// 
// Open MapServer .map file
//
$map = ms_newMapObj("/home/daniel/proj/msapps/gmap/htdocs/gmap75.map");

//
// Test setting extents member
//
$oldx = $map->extent->maxx;
print "test1 - before, maxx = $oldx\n";
$map->extent->setExtent(10, 20, 30, 40);
print "test1 - after, maxx = $oldx (shouldn't have changed)\n";
print "test1 - and the class member var. value is: ".$map->extent->maxx;

print "\n\n";

$oldx = $map->extent->maxx;
print "test2 - before, maxx = $oldx\n";
$map->extent->set("maxx", 123);
print "test2 - after, maxx = $oldx (shouldn't have changed)\n";
print "test2 - and the class member var. value is: ".$map->extent->maxx;

print "\n\n";

//
// Tests setting outputformat
//
$oldformat = $map->outputformat->name;
print "test3 - before, format = $oldformat\n";
$map->selectOutputFormat("JPEG");
print "test3 - after, format = $oldformat (shouldn't have changed)\n";
print "test3 - and the class member var. value is: ".$map->outputformat->name;

print "\n\n";

// 
// Test setting color
//
$oldcolor = $map->imagecolor->red;
print "test4 - before, map imagecolor.red = $oldcolor\n";
$map->imagecolor->setRGB(123, 150, 230);
print "test4 - after, map imagecolor.red = $oldcolor (shouldn't have 
changed)\n";
print "test4 - and the class member var. value is: ".$map->imagecolor->red;

print "\n\n";

//
// Test setting string params
//
$oldpath = $map->web->imagepath;
print "test5 - before, imagepath = $oldpath\n";
$map->web->set("imagepath", "/test123/");
print "test5 - after, imagepath = $oldpath (shouldn't have changed)\n";
print "test5 - and the class member var. value is: ".$map->web->imagepath;
print "\n\n";

?>

</PRE>
</HTML>


Note: See TracTickets for help on using tickets.