]> granicus.if.org Git - php/commitdiff
Fix handling of BIT fields for non-PS. We need
authorAndrey Hristov <andrey@php.net>
Tue, 22 Sep 2009 15:07:39 +0000 (15:07 +0000)
committerAndrey Hristov <andrey@php.net>
Tue, 22 Sep 2009 15:07:39 +0000 (15:07 +0000)
macros from mysqlnd to be able to convert a bit
stream to a number. BIT is binary data thus
the result is a string, and not unicode

ext/mysqli/mysqli.c

index bae5a8159e7761c8b13c94857d7caf20052e1c86..76266d2996d5e7354b1b2ffe78b9183fa2c4c8cb 100644 (file)
@@ -32,6 +32,7 @@
 #include "ext/standard/php_string.h"
 #include "php_mysqli_structs.h"
 #include "zend_exceptions.h"
+#include "ext/mysqlnd/mysqlnd_portability.h"
 
 ZEND_DECLARE_MODULE_GLOBALS(mysqli)
 static PHP_GINIT_FUNCTION(mysqli);
@@ -1218,14 +1219,40 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
                        zval *res;
 
                        MAKE_STD_ZVAL(res);
-                       if (!IS_BINARY_DATA(fields[i])) {
-                               UChar *ustr;
-                               int ulen;
 
-                               zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, row[i], field_len[i] TSRMLS_CC);
-                               ZVAL_UNICODEL(res, ustr, ulen, 0);
-                       } else {
-                               ZVAL_STRINGL(res, row[i], field_len[i], 1);     
+#if MYSQL_VERSION_ID > 50002
+                       if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) {
+                               my_ulonglong llval;
+                               char tmp[22];
+                               switch (field_len[i]) {
+                                       case 8:llval = (my_ulonglong)  bit_uint8korr(row[i]);break;
+                                       case 7:llval = (my_ulonglong)  bit_uint7korr(row[i]);break;
+                                       case 6:llval = (my_ulonglong)  bit_uint6korr(row[i]);break;
+                                       case 5:llval = (my_ulonglong)  bit_uint5korr(row[i]);break;
+                                       case 4:llval = (my_ulonglong)  bit_uint4korr(row[i]);break;
+                                       case 3:llval = (my_ulonglong)  bit_uint3korr(row[i]);break;
+                                       case 2:llval = (my_ulonglong)  bit_uint2korr(row[i]);break;
+                                       case 1:llval = (my_ulonglong)  uint1korr(row[i]);break;
+                               }
+                               /* even though lval is declared as unsigned, the value
+                                * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must
+                                * use MYSQLI_LL_SPEC.
+                                */
+                               snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval);
+                               /* numbers are latin1 and thus utf8, so no need to convert them with zend_string_to_unicode */
+                               ZVAL_STRING(res, tmp, 1);
+                       } else 
+#endif
+                       {
+                               if (!IS_BINARY_DATA(fields[i])) {
+                                       UChar *ustr;
+                                       int ulen;
+
+                                       zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, row[i], field_len[i] TSRMLS_CC);
+                                       ZVAL_UNICODEL(res, ustr, ulen, 0);
+                               } else {
+                                       ZVAL_STRINGL(res, row[i], field_len[i], 1);     
+                               }
                        }
 
                        if (fetchtype & MYSQLI_NUM) {