ID: 29583
Comment by: msisolak at yahoo dot com
Reported By: edwin at rabbito dot org
Status: Open
Bug Type: COM related
Operating System: Windows
PHP Version: 5CVS-2004-08-25 (dev)
New Comment:
I've dug into the COM error reported here and believe I have discovered
the issue. The problem is that com_object_cast() (in com_handlers.c)
assumes that the readobj and writeobj parameters will never be the same
object. That appears to work fine, except when the type conversion
request comes from the convert_object_to_type() macro
(zend_operators.c, line 264). In this case readobj == writeobj and we
end up with an access violation. Since _convert_to_string() uses
convert_object_to_type(), and _convert_to_string() is used when you try
to strlen() an object, com_object_cast() fails in the code from this bug
report.
Based on using sxe_object_cast() from the SimpleXML extension as a
example, I think that the freeing of the writeobj needs to be the last
thing done in the function rather than the first. The attached patch
uses that function as a model to move the zval_dtor() call to the end.
I also feel that the ZVAL_NULL(writeobj) should move after the
CDNO_FETCH(readobj). It seems to work as is, but only becuase
CDNO_FETCH() isn't checking that what is passed to it is really an
object.
I've played with this patch some and it seems to be holding, but I'm
looking at this with limited understanding of how the objects are
really being passed around so there may be an interaction here I'm not
seeing. With the patch applied, this PHP code:
echo strlen($rs->Fields(0)->Value), "\n";
echo date("F j, Y", variant_date_to_timestamp($rs->Fields(0)->Value)),
"\n";
echo date("F j, Y", variant_date_to_timestamp($rs->Fields(0))), "\n";
echo $rs->Fields(0)->Value, "\n";
echo $rs->Fields(0), "\n";
returns correct values in all five cases (for my test database):
8
January 1, 2001
January 1, 2001
1/1/2001
1/1/2001
--- php-5.0.1\ext\com_dotnet\com_handlers.c Wed Jul 28 19:48:26 2004
+++ com_handlers.c Thu Aug 19 15:18:45 2004
@@ -521,17 +521,17 @@
static int com_object_cast(zval *readobj, zval *writeobj, int type,
int should_free TSRMLS_DC)
{
+ zval free_obj;
php_com_dotnet_object *obj;
VARIANT v;
VARTYPE vt = VT_EMPTY;
if (should_free) {
- zval_dtor(writeobj);
+ free_obj = *writeobj;
}
- ZVAL_NULL(writeobj);
-
obj = CDNO_FETCH(readobj);
+ ZVAL_NULL(writeobj);
VariantInit(&v);
if (V_VT(&obj->v) == VT_DISPATCH) {
@@ -569,6 +569,9 @@
php_com_zval_from_variant(writeobj, &v, obj->code_page TSRMLS_CC);
VariantClear(&v);
+ if (should_free) {
+ zval_dtor(&free_obj);
+ }
return SUCCESS;
}
Previous Comments:
------------------------------------------------------------------------
[2004-08-25 04:53:32] edwin at rabbito dot org
Same error as of 2004-08-25:
Application Error -
The instruction at "0x009dab5e" referenced memory at "0x00000003". The
memory could not be "read".
------------------------------------------------------------------------
[2004-08-10 03:46:16] edwin at rabbito dot org
ie)
php.exe - Application Error
The instruction at "0x1008a9de" referenced memory at "0x00000003". The
memory could not be "read".
------------------------------------------------------------------------
[2004-08-10 03:22:19] edwin at rabbito dot org
There is no output from the CLI, apart from the Dr. Watson exception
dialog:
An application error has occurred and an application error log is being
generated.
php.exe
Exception: access violation (0xc0000005), Address: 0x1008a9de.
------------------------------------------------------------------------
[2004-08-09 12:44:38] [EMAIL PROTECTED]
Crash or exception?
Paste the output you see from the CLI here please.
------------------------------------------------------------------------
[2004-08-09 11:54:27] edwin at rabbito dot org
Description:
------------
When trying to retrieve a date field from an Access 97 database, the
actual data returned is different from PHP4 (PHP 4 returns a timestamp,
whereas PHP 5 returns a date, ie) 02/04/04 instead of a timestamp). By
calling the code (as attached) in PHP5, PHP does not return error
gracefully, but crashes.
(seems to be something that is not yet fixed in bug#29392)
Reproduce code:
---------------
$security="C:\access97.mdw";
$user="access";
$password="access";
$dsn="Driver={Microsoft Access Driver (*.mdb)};
DBQ=$database;SystemDB=$security;Uid=$user;Pwd=$password";
$db = new COM("ADODB.Connection");
$db->open($dsn);
$query="SELECT DateField1 FROM [Table1];";
$rs = $db->execute($query);
if (!$rs->EOF()) {
echo strlen($rs->Fields(0)->Value);
}
Expected result:
----------------
Either an error should be returned due to invalid type
($rs->Fields(0)->Value in date type), or the actual length the the date
string.
Actual result:
--------------
PHP crashed
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=29583&edit=1