|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2000-06-09 12:01 UTC] andi at cvs dot php dot net
[2000-06-10 03:08 UTC] zeev at cvs dot php dot net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sun Dec 14 20:00:01 2025 UTC |
Synopsis: it appears that zend_get_parameter_array_ex() may corrupt values if called for param_count < ARG_COUNT(ht) Background: im in the process of implementing an ANSI like sscanf() and fscanf(). a common routine, php_internal_sscanf(), is referenced by both routines to perform the actual work. PHPAPI int php_internal_sscanf(char *string,char *format, int ht,int varstart,zval **return_value) the prototype for (f|s)scanf() is : mixed sscanf($string,$format,...) mixed sscanf($file_handle,$format,...) (f|s)scanf works in two modes : with and without variables passed by reference. without variables, it returns an array of elements parsed from the literal string. this seems to work fine (subject to further testing). when variables are passed in, the function modifies the variables directly (as in "c"). this is where the issue lies. every time i pass in more than 2 variables, the value of the first two variables are hosed. Details: in PHP_FUNCTION(sscanf) i do the following : if ((ARG_COUNT(ht) < 2) || (zend_get_parameters_ex(ht,2,&literal,&format) == FAILURE)) { WRONG_PARAM_COUNT; } convert_to_string_ex( literal ); convert_to_string_ex( format ); php_internal_sscanf( (*literal)->value.str.val, (*format)->value.str.val, ht, 2, &return_value ); in php_sscanf_internal, i check the validity of format, then i grab the all the other parameters as an array from ht : zval ***args args = (zval ***)emalloc(ARG_COUNT(ht) * sizeof(zval **)); if (zend_get_parameters_array_ex(ARG_COUNT(ht), args) == FAILURE) { efree(args); COMPLAIN_LOUDLY; /* you get the point */ return FAILURE } i need to do things in this two-phase this way to allow the internal scanning routine to do work for both fscanf() and scanf(). actually in my testing, it does not even reach this far (the validation above it fails on the bogus values). Setup: Linux Mandrake 7.0 running on a Pentium (classic) 166Mhz, 64M. PHP 4.0.0 './configure' '--with-apxs' '--enable-calendar' '--with-gd=shared' '--with-imap' '--with-mcal=/usr/local/lib' '--with-mysql' '--with-pgsql' '--enable-trans-sid' '--enable-wddx' '--enable-sysvshm' '--enable-sysvmem' '--with-regex=php' '--with-gdbm' '--with-mhash' '--enable-memory_limit' '--enable-ftp' '--with-cybercash' '--with-ldap' thread safety disabled allow_call_time_pass_reference on Analysis : as far as i can reduce it, the problem seems to be in PHP_FUNCTION(sscanf) with the zend_get_parameters_ex() function. if only two parameters are passed in, then all is well. if more parameters are passed than is first retrieved, then the values assigned to the first two variables are either "", "-1", or "0" . i verified this by inserting zend_printf() calls just as after the convert_to_string_ex() calls to output the values of the string variables. Postscript: just to investigate other alternatives, i changed the prototype for php_scanf_internal to : PHPAPI int php_sscanf_internal(char *string,char *format,int ht,int argCount,zval ***args, int varStart,pval **return_value); (note ht is needed to be able to check that all variables are passed by reference) i made the corresponding changes in PHP_FUNCTION(sscanf) and PHP_FUNCTION(fscanf) to read the entire param array, getting the appropriate values from there, then passing the array php_sscanf_internal(). from initial indications, it seems to pass values correctly, backing my feeling that zend_get_parameters_ex() may be doing something funny. Bottom Line: any insight is appreciated. if this is a WAD, then it should be note in the developer documentation to spare someone else the trouble. clayton collie PHP Enthusiast (PHPnut!)