Skip to content

Commit e3012d0

Browse files
committed
Merge branch 'master' of https://git.php.net/repository/php-src
2 parents 124fb22 + 961da40 commit e3012d0

File tree

9 files changed

+160
-100
lines changed

9 files changed

+160
-100
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Error cases of compound shift assignment on strings
3+
--FILE--
4+
<?php
5+
6+
$n = "65";
7+
$n <<= $n;
8+
var_dump($n);
9+
10+
$n = "-1";
11+
$n <<= $n;
12+
var_dump($n);
13+
14+
$n = "65";
15+
$n >>= $n;
16+
var_dump($n);
17+
18+
$n = "-1";
19+
$n >>= $n;
20+
var_dump($n);
21+
22+
$n = "0";
23+
$n %= $n;
24+
var_dump($n);
25+
26+
$n = "-1";
27+
$n %= $n;
28+
var_dump($n);
29+
--EXPECTF--
30+
int(0)
31+
32+
Warning: Bit shift by negative number in %s on line %d
33+
bool(false)
34+
int(0)
35+
36+
Warning: Bit shift by negative number in %s on line %d
37+
bool(false)
38+
39+
Warning: Division by zero in %s on line %d
40+
bool(false)
41+
int(0)

Zend/zend_operators.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,10 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
11431143
zend_long op1_lval, op2_lval;
11441144

11451145
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
1146+
1147+
if (op1 == result) {
1148+
zval_dtor(result);
1149+
}
11461150

11471151
if (op2_lval == 0) {
11481152
zend_error(E_WARNING, "Division by zero");
@@ -1156,9 +1160,6 @@ ZEND_API int mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
11561160
return SUCCESS;
11571161
}
11581162

1159-
if (op1 == result) {
1160-
zval_dtor(result);
1161-
}
11621163
ZVAL_LONG(result, op1_lval % op2_lval);
11631164
return SUCCESS;
11641165
}
@@ -1451,6 +1452,10 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
14511452

14521453
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
14531454

1455+
if (op1 == result) {
1456+
zval_dtor(result);
1457+
}
1458+
14541459
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
14551460
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
14561461
if (EXPECTED(op2_lval > 0)) {
@@ -1463,9 +1468,6 @@ ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
14631468
}
14641469
}
14651470

1466-
if (op1 == result) {
1467-
zval_dtor(result);
1468-
}
14691471
ZVAL_LONG(result, op1_lval << op2_lval);
14701472
return SUCCESS;
14711473
}
@@ -1477,6 +1479,10 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
14771479

14781480
convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
14791481

1482+
if (op1 == result) {
1483+
zval_dtor(result);
1484+
}
1485+
14801486
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
14811487
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
14821488
if (EXPECTED(op2_lval > 0)) {
@@ -1489,9 +1495,6 @@ ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
14891495
}
14901496
}
14911497

1492-
if (op1 == result) {
1493-
zval_dtor(result);
1494-
}
14951498
ZVAL_LONG(result, op1_lval >> op2_lval);
14961499
return SUCCESS;
14971500
}

ext/mysqli/mysqli_api.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "zend_smart_str.h"
3434
#include "php_mysqli_structs.h"
3535
#include "mysqli_priv.h"
36+
#include "ext/mysqlnd/mysql_float_to_double.h"
3637

3738

3839
#if !defined(MYSQLI_USE_MYSQLND)
@@ -413,8 +414,17 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval *args, unsigned int argc, un
413414
col_type = (stmt->stmt->fields) ? stmt->stmt->fields[ofs].type : MYSQL_TYPE_STRING;
414415

415416
switch (col_type) {
416-
case MYSQL_TYPE_DOUBLE:
417417
case MYSQL_TYPE_FLOAT:
418+
stmt->result.buf[ofs].type = IS_DOUBLE;
419+
stmt->result.buf[ofs].buflen = sizeof(float);
420+
421+
stmt->result.buf[ofs].val = (char *)emalloc(sizeof(float));
422+
bind[ofs].buffer_type = MYSQL_TYPE_FLOAT;
423+
bind[ofs].buffer = stmt->result.buf[ofs].val;
424+
bind[ofs].is_null = &stmt->result.is_null[ofs];
425+
break;
426+
427+
case MYSQL_TYPE_DOUBLE:
418428
stmt->result.buf[ofs].type = IS_DOUBLE;
419429
stmt->result.buf[ofs].buflen = sizeof(double);
420430

@@ -1021,8 +1031,22 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS)
10211031
}
10221032
break;
10231033
case IS_DOUBLE:
1024-
ZVAL_DOUBLE(result, *(double *)stmt->result.buf[i].val);
1034+
{
1035+
double dval;
1036+
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_FLOAT) {
1037+
#ifndef NOT_FIXED_DEC
1038+
# define NOT_FIXED_DEC 31
1039+
#endif
1040+
dval = mysql_float_to_double(*(float *)stmt->result.buf[i].val,
1041+
(stmt->stmt->fields[i].decimals >= NOT_FIXED_DEC) ? -1 :
1042+
stmt->stmt->fields[i].decimals);
1043+
} else {
1044+
dval = *((double *)stmt->result.buf[i].val);
1045+
}
1046+
1047+
ZVAL_DOUBLE(result, dval);
10251048
break;
1049+
}
10261050
case IS_STRING:
10271051
if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG
10281052
#if MYSQL_VERSION_ID > 50002

ext/mysqli/tests/010.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,18 @@ mysqli_close($link);
6262
--EXPECT--
6363
array(7) {
6464
[0]=>
65-
float(3.141593)
65+
float(3.14159)
6666
[1]=>
6767
float(-1.0E-6)
6868
[2]=>
6969
float(0)
7070
[3]=>
7171
float(1.0E+12)
7272
[4]=>
73-
float(0.5646425)
73+
float(0.564642)
7474
[5]=>
7575
float(1)
7676
[6]=>
77-
float(8.888889E+14)
77+
float(8.88889E+14)
7878
}
7979
done!

ext/mysqli/tests/bug67839.phpt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,27 @@ precision=5
3838
die();
3939
}
4040

41-
if (!mysqli_stmt_execute($stmt)) {
41+
$id = null;
42+
$fp4 = null;
43+
$fp8 = null;
44+
45+
if (!mysqli_stmt_bind_result($stmt, $id, $fp4, $fp8)) {
4246
printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
4347
die();
4448
}
4549

46-
47-
if (!($result = mysqli_stmt_get_result($stmt))) {
50+
if (!mysqli_stmt_execute($stmt)) {
4851
printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
4952
die();
5053
}
5154

52-
$data = mysqli_fetch_assoc($result);
53-
print $data['id'] . ": " . $data['fp4'] . ": " . $data['fp8'] . "\n";
55+
56+
if (!(mysqli_stmt_fetch($stmt))) {
57+
printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
58+
die();
59+
}
60+
61+
print $id . ": " . $fp4 . ": " . $fp8 . "\n";
5462
?>
5563
--CLEAN--
5664
<?php

ext/mysqlnd/config9.m4

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -49,34 +49,3 @@ fi
4949
if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then
5050
PHP_ADD_BUILD_DIR([ext/mysqlnd], 1)
5151
fi
52-
53-
dnl
54-
dnl Check if the compiler supports Decimal32/64/128 types from the IEEE-754 2008 version
55-
dnl References: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1657.pdf
56-
dnl http://speleotrove.com/decimal/
57-
dnl
58-
AC_CACHE_CHECK([whether whether compiler supports Decimal32/64/128 types], ac_cv_decimal_fp_supported,[
59-
AC_TRY_RUN( [
60-
#include <stdio.h>
61-
#include <string.h>
62-
63-
int main(int argc, char **argv) {
64-
typedef float dec32 __attribute__((mode(SD)));
65-
dec32 k = 99.49f;
66-
double d2 = (double)k;
67-
const char *check_str = "99.49";
68-
char print_str[32];
69-
70-
snprintf(print_str, 32, "%f", d2);
71-
return memcmp(print_str, check_str, 5);
72-
}
73-
],[
74-
ac_cv_decimal_fp_supported=yes
75-
],[
76-
ac_cv_decimal_fp_supported=no
77-
],[
78-
ac_cv_decimal_fp_supported=no
79-
])])
80-
if test "$ac_cv_decimal_fp_supported" = "yes"; then
81-
AC_DEFINE(HAVE_DECIMAL_FP_SUPPORT, 1, [Define if the compiler supports Decimal32/64/128 types.])
82-
fi

ext/mysqlnd/mysql_float_to_double.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 5 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 2006-2014 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Keyur Govande <[email protected]> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#ifndef MYSQL_FLOAT_TO_DOUBLE_H
20+
#define MYSQL_FLOAT_TO_DOUBLE_H
21+
22+
#include "main/php.h"
23+
#include <float.h>
24+
#include "main/snprintf.h"
25+
26+
#define MAX_CHAR_BUF_LEN 255
27+
28+
#ifndef FLT_DIG
29+
# define FLT_DIG 6
30+
#endif
31+
32+
/*
33+
* Convert from a 4-byte float to a 8-byte decimal by first converting
34+
* the float to a string, and then the string to a double.
35+
* The decimals argument specifies the precision of the output. If decimals
36+
* is less than zero, then a gcvt(3) like logic is used with the significant
37+
* digits set to FLT_DIG i.e. 6.
38+
*/
39+
static inline double mysql_float_to_double(float fp4, int decimals) {
40+
char num_buf[MAX_CHAR_BUF_LEN]; /* Over allocated */
41+
42+
if (decimals < 0) {
43+
php_gcvt(fp4, FLT_DIG, '.', 'e', num_buf);
44+
} else {
45+
php_sprintf(num_buf, "%.*f", decimals, fp4);
46+
}
47+
48+
return zend_strtod(num_buf, NULL);
49+
}
50+
51+
/*
52+
* Local variables:
53+
* tab-width: 4
54+
* c-basic-offset: 4
55+
* End:
56+
* vim600: noet sw=4 ts=4 fdm=marker
57+
* vim<600: noet sw=4 ts=4
58+
*/
59+
60+
#endif /* MYSQL_FLOAT_TO_DOUBLE_H */

ext/mysqlnd/mysqlnd_ps_codec.c

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "mysqlnd_wireprotocol.h"
2525
#include "mysqlnd_priv.h"
2626
#include "mysqlnd_debug.h"
27+
#include "ext/mysqlnd/mysql_float_to_double.h"
2728

2829
#define MYSQLND_SILENT
2930

@@ -181,56 +182,12 @@ ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_l
181182
(*row)+= 4;
182183
DBG_INF_FMT("value=%f", fval);
183184

184-
/*
185-
* The following is needed to correctly support 4-byte floats.
186-
* Otherwise, a value of 9.99 in a FLOAT column comes out of mysqli
187-
* as 9.9998998641968.
188-
*
189-
* For GCC, we use the built-in decimal support to "up-convert" a
190-
* 4-byte float to a 8-byte double.
191-
* When that is not available, we fall back to converting the float
192-
* to a string and then converting the string to a double. This mimics
193-
* what MySQL does.
194-
*/
195-
#ifdef HAVE_DECIMAL_FP_SUPPORT
196-
{
197-
typedef float dec32 __attribute__((mode(SD)));
198-
/* volatile so the compiler will not optimize away the conversion */
199-
volatile dec32 d32val = fval;
200-
201-
/* The following cast is guaranteed to do the right thing */
202-
dval = (double) d32val;
203-
}
204-
#elif defined(PHP_WIN32)
205-
{
206-
/* float datatype on Winows is already 4 byte but has a precision of 7 digits */
207-
char num_buf[2048];
208-
(void)_gcvt_s(num_buf, 2048, fval, field->decimals >= 31 ? 7 : field->decimals);
209-
dval = zend_strtod(num_buf, NULL);
210-
}
211-
#else
212-
{
213-
char num_buf[2048]; /* Over allocated */
214-
char *s;
215-
216-
#ifndef FLT_DIG
217-
# define FLT_DIG 6
218-
#endif
219-
/* Convert to string. Ignoring localization, etc.
220-
* Following MySQL's rules. If precision is undefined (NOT_FIXED_DEC i.e. 31)
221-
* or larger than 31, the value is limited to 6 (FLT_DIG).
222-
*/
223-
s = php_gcvt(fval,
224-
field->decimals >= 31 ? FLT_DIG : field->decimals,
225-
'.',
226-
'e',
227-
num_buf);
228-
229-
/* And now convert back to double */
230-
dval = zend_strtod(s, NULL);
231-
}
185+
#ifndef NOT_FIXED_DEC
186+
# define NOT_FIXED_DEC 31
232187
#endif
233188

189+
dval = mysql_float_to_double(fval, (field->decimals >= NOT_FIXED_DEC) ? -1 : field->decimals);
190+
234191
ZVAL_DOUBLE(zv, dval);
235192
DBG_VOID_RETURN;
236193
}

sapi/fpm/fpm/fastcgi.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@
3737

3838
#include <windows.h>
3939

40-
typedef unsigned int in_addr_t;
41-
4240
struct sockaddr_un {
4341
short sun_family;
4442
char sun_path[MAXPATHLEN];

0 commit comments

Comments
 (0)