xref: /PHP-8.4/ext/mysqli/tests/bug49442.phpt (revision a21edc52)
1--TEST--
2Bug #49422 (mysqlnd: mysqli_real_connect() and LOAD DATA INFILE crash)
3--EXTENSIONS--
4mysqli
5--SKIPIF--
6<?php
7require_once 'connect.inc';
8
9$link = mysqli_init();
10if (!@my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) {
11    die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
12}
13
14include_once "local_infile_tools.inc";
15if ($msg = check_local_infile_support($link, $engine))
16    die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
17
18mysqli_close($link);
19?>
20--INI--
21mysqli.allow_local_infile=1
22mysqli.allow_persistent=1
23mysqli.max_persistent=1
24--FILE--
25<?php
26    include 'connect.inc';
27
28    $link = mysqli_init();
29    if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) {
30        printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
31    }
32
33    if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) {
34        printf("[002] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
35    }
36
37    if (!mysqli_query($link, 'CREATE TABLE test(id INT, label CHAR(1), PRIMARY KEY(id)) ENGINE=' . $engine)) {
38        printf("[003] Failed to create test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
39    }
40
41    include "local_infile_tools.inc";
42    $file = create_standard_csv(4);
43
44    if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s'
45            INTO TABLE test
46            FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\''
47            LINES TERMINATED BY '\n'",
48            mysqli_real_escape_string($link, $file)))) {
49            printf("[005] [%d] %s\n",  mysqli_errno($link), mysqli_error($link));
50    }
51
52    if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id"))
53        printf("[006] [%d] %s\n",  mysqli_errno($link), mysqli_error($link));
54
55    $rows = array();
56    while ($row = mysqli_fetch_assoc($res)) {
57        var_dump($row);
58        $rows[] = $row;
59    }
60
61    mysqli_free_result($res);
62
63    mysqli_query($link, "DELETE FROM test");
64    mysqli_close($link);
65
66    /*
67        mysqlnd makes a connection created through mysql_init()/mysqli_real_connect() always a 'persistent' one.
68        At this point 'persistent' is not to be confused with what a user calls a 'persistent' - in this case
69        'persistent' means that mysqlnd uses malloc() instead of emalloc(). nothing else. ext/mysqli will
70        not consider it as a 'persistent' connection in a user sense, ext/mysqli will not apply max_persistent etc.
71        It's only about malloc() vs. emalloc().
72
73        However, the bug is about malloc() and efree(). You can make mysqlnd use malloc() by either using
74        pconnect or mysql_init() - so we should test pconnect as well.
75    */
76    $host = 'p:' . $host;
77    if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
78        printf("[007] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
79    }
80
81    /* bug happened during query processing */
82    if (!@mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s'
83        INTO TABLE test
84        FIELDS TERMINATED BY ';' OPTIONALLY ENCLOSED BY '\''
85        LINES TERMINATED BY '\n'",
86        mysqli_real_escape_string($link, $file)))) {
87        printf("[008] [%d] %s\n",  mysqli_errno($link), mysqli_error($link));
88    }
89
90    /* we survived? that's good enough... */
91
92    if (!$res = mysqli_query($link, "SELECT * FROM test ORDER BY id"))
93        printf("[009] [%d] %s\n",  mysqli_errno($link), mysqli_error($link));
94
95    $i = 0;
96    while ($row = mysqli_fetch_assoc($res)) {
97        if (($row['id'] != $rows[$i]['id']) || ($row['label'] != $rows[$i]['label'])) {
98            printf("[010] Wrong values, check manually!\n");
99        }
100        $i++;
101    }
102    mysqli_close($link);
103
104    print "done!";
105?>
106--CLEAN--
107<?php
108require_once 'clean_table.inc';
109?>
110--EXPECT--
111array(2) {
112  ["id"]=>
113  string(2) "97"
114  ["label"]=>
115  string(1) "x"
116}
117array(2) {
118  ["id"]=>
119  string(2) "98"
120  ["label"]=>
121  string(1) "y"
122}
123array(2) {
124  ["id"]=>
125  string(2) "99"
126  ["label"]=>
127  string(1) "z"
128}
129done!
130