-
Notifications
You must be signed in to change notification settings - Fork 7.9k
fix ora-03131 on bigendian 64bit machines #7422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
out-variables cannot be used on bigendian 64bit machines and cause ORA-03131 error This is caused by a uc4-value (length of OCI8-data) stored into the upper half of a sizte_t-value (length of zend_string).
ext/oci8/oci8_statement.c
Outdated
@@ -1500,6 +1500,10 @@ sb4 php_oci_bind_out_callback( | |||
|
|||
/* XXX we assume that zend-zval len has 4 bytes */ | |||
*alenpp = (ub4*) &Z_STRLEN_P(val); | |||
if(sizeof(size_t)==2*sizeof(ub4)){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A solution using the config.m4 macro PHP_C_BIGENDIAN would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this can check #ifdef WORDS_BIGENDIAN
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using WORDS_BIGENDIAN now.
Are there bigendian-machines with sizeof(size_t)==sizeof(ub4)
or sizeof(size_t)==4*sizeof(ub4)
?
Hence I'm increasing the ub4-pointer only if sizeof(size_t)==2*sizeof(ub4)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pk1234, I don't know the answer to that question, sorry. Overall I still feel this if
test needs to be done at compile time and a macro defined. See how AC_COMPILE_IFELSE is used in other configure files. Sorry I don't have access to a big endian machine to check this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cjbj, current code does not work at all on 64bit bigendian machines. So everything that changes the behaviour on bigendian systems only, will be better than what have now.
#ifdef WORDS_BIGENDIAN makes sure that the proposed changes do not influence littleendian systems.
Creating a new macro that will be defined if and only if sizeof(size_t)==2*sizeof(ub4)
seems to be too much effort to me.
sizeof(size_t)==2*sizeof(ub4)
can be evaluated at compile time and the optimizer will either do or remove the increment-statement unconditionally. That's exactly the effect of a #ifdef SIZE_T_HAS_TWICE_THE_SIZE_OF_UB4-macro
I therefore feel, that my combination of #ifdef WORDS_BIGENDIAN and if-statement is the best way to go without lots of bigendian/littleendian test-machines.
instead of reading first 4 bytes of (size_t)1 to detect bigendieness use WORDS_BIGENDIAN macro
another typo - sorry for 3 commits
@pk1234 I'm out for a few days. I'll get back to this next week. |
@cjbj no problem |
Is there anything I can do? Peter |
OCI8 stores the length of retrieved data as a uc4-value into the first 4 bytes of the length of a zend_string (size_t). This fails on bigendian 64bit machines where the length must be stored into the LAST 4 bytes of zend_string-length.
This patches fixes the problem by increasing the *uc4-pointer if the first 4 bytes of (sizte_t)1 are equal to 0.