Issues (994)

src/shim/mysql.php (44 issues)

1
<?php
2
3
/**
4
 * php7-mysql-shim
5
 *
6
 * @author Davey Shafik <[email protected]>
7
 * @copyright Copyright (c) 2017 Davey Shafik
8
 * @license MIT License
9
 * @link https://github.com/dshafik/php7-mysql-shim
10
 */
11
12
/**
13
 * A drop-in replacement for ext/mysql in PHP 7+ using ext/mysqli instead
14
 *
15
 * This library is meant to be a _stop-gap_. It will be slower than using
16
 * the native functions directly.
17
 *
18
 * You should switch to ext/pdo_mysql or ext/mysqli, and migrate to prepared
19
 * queries (@see http://php.net/manual/en/pdo.prepared-statements.php) to
20
 * ensure you are securely interacting with your database.
21
 */
22
23
namespace {
24
25
  if (!extension_loaded('mysql')) {
26
    if (!extension_loaded('mysqli')) {
27
      trigger_error('php7-mysql-shim: ext/mysqli is required', E_USER_ERROR);
28
    }
29
30
    define('MYSQL_ASSOC', 1);
31
    define('MYSQL_NUM', 2);
32
    define('MYSQL_BOTH', 3);
33
    define('MYSQL_CLIENT_COMPRESS', 32);
34
    define('MYSQL_CLIENT_SSL', 2048);
35
    define('MYSQL_CLIENT_INTERACTIVE', 1024);
36
    define('MYSQL_CLIENT_IGNORE_SPACE', 256);
37
38
    function mysql_connect(
39
      $hostname = null,
40
      $username = null,
41
      $password = null,
42
      $new = false,
43
      $flags = 0
44
    ) {
45
      if (null === $hostname) {
46
        $hostname = ini_get('mysqli.default_host') ?: null;
47
      }
48
      if (null === $username) {
49
        $username = ini_get('mysqli.default_user') ?: null;
50
      }
51
      if (null === $password) {
52
        $password = ini_get('mysqli.default_pw') ?: null;
53
      }
54
55
      $hash = sha1($hostname . $username . $flags);
56
      /* persistent connections start with p: */
57
      /* don't use a cached link for those */
58
      if (!$new && $hostname[1] !== ':' && isset(\UniversalFramework\MySQL::$connections[$hash])) {
59
        \UniversalFramework\MySQL::$last_connection = \UniversalFramework\MySQL::$connections[$hash]['conn'];
60
        \UniversalFramework\MySQL::$connections[$hash]['refcount'] += 1;
61
        return \UniversalFramework\MySQL::$connections[$hash]['conn'];
62
      }
63
64
      /* A custom port can be specified by appending the hostname with :{port} e.g. hostname:3307 */
65
      if (preg_match('/^(.+):([\d]+)$/', $hostname, $port_matches) === 1 && $port_matches[1] !== "p") {
66
        $hostname = $port_matches[1];
67
        $port = (int) $port_matches[2];
68
      } else {
69
        $port = null;
70
      }
71
72
      /* No flags, means we can use mysqli_connect() */
73
      if ($flags === 0) {
74
        $conn = mysqli_connect($hostname, $username, $password, '', $port);
0 ignored issues
show
The call to mysqli_connect() has too few arguments starting with socket. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

74
        $conn = /** @scrutinizer ignore-call */ mysqli_connect($hostname, $username, $password, '', $port);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
75
        if (!$conn instanceof mysqli) {
76
          return false;
77
        }
78
        \UniversalFramework\MySQL::$last_connection = $conn;
79
        $conn->hash = $hash;
0 ignored issues
show
The property hash does not seem to exist on mysqli.
Loading history...
80
        \UniversalFramework\MySQL::$connections[$hash] = array('refcount' => 1, 'conn' => $conn);
81
82
        return $conn;
83
      }
84
85
      /* Flags means we need to use mysqli_real_connect() instead, and handle exceptions */
86
      try {
87
        \UniversalFramework\MySQL::$last_connection = $conn = mysqli_init();
88
89
        mysqli_real_connect(
90
          $conn,
91
          $hostname,
92
          $username,
93
          $password,
94
          '',
95
          $port,
96
          '',
97
          $flags
98
        );
99
100
        // @codeCoverageIgnoreStart
101
        // PHPUnit turns the warning from mysqli_real_connect into an exception, so this never runs
102
        if ($conn === false) {
103
          return false;
104
        }
105
        // @codeCoverageIgnoreEnd
106
107
        $conn->hash = $hash;
108
        \UniversalFramework\MySQL::$connections[$hash] = array('refcount' => 1, 'conn' => $conn);
109
110
        return $conn;
111
      } catch (\Throwable $e) {
112
        trigger_error($e->getMessage(), E_USER_WARNING);
113
        // @codeCoverageIgnoreStart
114
        // PHPUnit turns the warning into an exception, so this never runs
115
        return false;
116
        // @codeCoverageIgnoreEnd
117
      }
118
    }
119
120
    function mysql_pconnect(
121
      $hostname = null,
122
      $username = null,
123
      $password = null,
124
      $flags = 0
125
    ) {
126
      $hostname = 'p:' . $hostname;
127
      return mysql_connect($hostname, $username, $password, false, $flags);
128
    }
129
130
    function mysql_close(\mysqli $link = null)
131
    {
132
      $isDefault = ($link === null);
133
134
      $link = \UniversalFramework\MySQL::getConnection($link, __FUNCTION__);
0 ignored issues
show
__FUNCTION__ of type string is incompatible with the type UniversalFramework\function expected by parameter $func of UniversalFramework\MySQL::getConnection(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

134
      $link = \UniversalFramework\MySQL::getConnection($link, /** @scrutinizer ignore-type */ __FUNCTION__);
Loading history...
135
      if ($link === null) {
136
        // @codeCoverageIgnoreStart
137
        // PHPUnit Warning -> Exception
138
        return false;
139
        // @codeCoverageIgnoreEnd
140
      }
141
142
      if (isset(\UniversalFramework\MySQL::$connections[$link->hash])) {
0 ignored issues
show
The property hash does not seem to exist on mysqli.
Loading history...
143
        \UniversalFramework\MySQL::$connections[$link->hash]['refcount'] -= 1;
144
      }
145
146
      $return = true;
147
      if (\UniversalFramework\MySQL::$connections[$link->hash]['refcount'] === 0) {
148
        $return = mysqli_close($link);
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_close() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

148
        $return = mysqli_close(/** @scrutinizer ignore-type */ $link);
Loading history...
149
        unset(\UniversalFramework\MySQL::$connections[$link->hash]);
150
      }
151
152
      if ($isDefault) {
153
        UniversalFramework\MySQL::$last_connection = null;
154
      }
155
156
      return $return;
157
    }
158
159
    function mysql_select_db($databaseName, \mysqli $link = null)
160
    {
161
      $link = \UniversalFramework\MySQL::getConnection($link);
162
163
      return mysqli_query(
164
        $link,
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_query() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        /** @scrutinizer ignore-type */ $link,
Loading history...
165
        'USE `' . mysqli_real_escape_string($link, $databaseName) . '`'
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_real_escape_string() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

165
        'USE `' . mysqli_real_escape_string(/** @scrutinizer ignore-type */ $link, $databaseName) . '`'
Loading history...
166
      ) !== false;
167
    }
168
169
    function mysql_query($query, \mysqli $link = null)
170
    {
171
      return mysqli_query(\UniversalFramework\MySQL::getConnection($link), $query);
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_query() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

171
      return mysqli_query(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link), $query);
Loading history...
172
    }
173
174
    function mysql_unbuffered_query($query, \mysqli $link = null)
175
    {
176
      $link = \UniversalFramework\MySQL::getConnection($link);
177
      if (mysqli_real_query($link, $query)) {
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_real_query() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

177
      if (mysqli_real_query(/** @scrutinizer ignore-type */ $link, $query)) {
Loading history...
178
        return mysqli_use_result($link);
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_use_result() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

178
        return mysqli_use_result(/** @scrutinizer ignore-type */ $link);
Loading history...
179
      }
180
181
      return false;
182
    }
183
184
    function mysql_db_query($databaseName, $query, \mysqli $link = null)
185
    {
186
      if (mysql_select_db($databaseName, $link)) {
0 ignored issues
show
It seems like $link can also be of type mysqli; however, parameter $link_identifier of mysql_select_db() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

186
      if (mysql_select_db($databaseName, /** @scrutinizer ignore-type */ $link)) {
Loading history...
187
        return mysql_query($query, $link);
0 ignored issues
show
It seems like $link can also be of type mysqli; however, parameter $link_identifier of mysql_query() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
        return mysql_query($query, /** @scrutinizer ignore-type */ $link);
Loading history...
188
      }
189
      return false;
190
    }
191
192
    function mysql_list_dbs(\mysqli $link = null)
193
    {
194
      return mysql_query('SHOW DATABASES', $link);
0 ignored issues
show
It seems like $link can also be of type mysqli; however, parameter $link_identifier of mysql_query() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

194
      return mysql_query('SHOW DATABASES', /** @scrutinizer ignore-type */ $link);
Loading history...
195
    }
196
197
    function mysql_list_tables($databaseName, \mysqli $link = null)
198
    {
199
      $link = \UniversalFramework\MySQL::getConnection($link);
200
      $query = sprintf(
201
        'SHOW TABLES FROM `%s`',
202
        mysql_real_escape_string($databaseName, $link)
0 ignored issues
show
$link of type false|mysqli is incompatible with the type resource expected by parameter $link_identifier of mysql_real_escape_string(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

202
        mysql_real_escape_string($databaseName, /** @scrutinizer ignore-type */ $link)
Loading history...
203
      );
204
      return mysql_query($query, $link);
0 ignored issues
show
$link of type false|mysqli is incompatible with the type resource expected by parameter $link_identifier of mysql_query(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

204
      return mysql_query($query, /** @scrutinizer ignore-type */ $link);
Loading history...
205
    }
206
207
    function mysql_list_fields($databaseName, $tableName, \mysqli $link = null)
208
    {
209
      $link = \UniversalFramework\MySQL::getConnection($link);
210
211
      $query = sprintf(
212
        'SHOW COLUMNS FROM `%s`.`%s`',
213
        mysqli_real_escape_string($link, $databaseName),
0 ignored issues
show
It seems like $link can also be of type false; however, parameter $mysql of mysqli_real_escape_string() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

213
        mysqli_real_escape_string(/** @scrutinizer ignore-type */ $link, $databaseName),
Loading history...
214
        mysqli_real_escape_string($link, $tableName)
215
      );
216
217
      $result = mysql_query($query, $link);
0 ignored issues
show
$link of type false|mysqli is incompatible with the type resource expected by parameter $link_identifier of mysql_query(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

217
      $result = mysql_query($query, /** @scrutinizer ignore-type */ $link);
Loading history...
218
219
      if ($result instanceof \mysqli_result) {
0 ignored issues
show
$result is never a sub-type of mysqli_result.
Loading history...
220
        $result->table = $tableName;
221
        return $result;
222
      }
223
224
      trigger_error('mysql_list_fields(): Unable to save MySQL query result', E_USER_WARNING);
225
      // @codeCoverageIgnoreStart
226
      return false;
227
      // @codeCoverageIgnoreEnd
228
    }
229
230
    function mysql_list_processes(\mysqli $link = null)
231
    {
232
      return mysql_query('SHOW PROCESSLIST', $link);
0 ignored issues
show
It seems like $link can also be of type mysqli; however, parameter $link_identifier of mysql_query() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

232
      return mysql_query('SHOW PROCESSLIST', /** @scrutinizer ignore-type */ $link);
Loading history...
233
    }
234
235
    function mysql_error(\mysqli $link = null)
236
    {
237
      return mysqli_error(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_error() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

237
      return mysqli_error(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
238
    }
239
240
    function mysql_errno(\mysqli $link = null)
241
    {
242
      return mysqli_errno(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_errno() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

242
      return mysqli_errno(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
243
    }
244
245
    function mysql_affected_rows(\mysqli $link = null)
246
    {
247
      return mysqli_affected_rows(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_affected_rows() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

247
      return mysqli_affected_rows(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
248
    }
249
250
    function mysql_insert_id($link = null) /*|*/
251
    {
252
      return mysqli_insert_id(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_insert_id() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

252
      return mysqli_insert_id(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
253
    }
254
255
    function mysql_result($result, $row, $field = 0)
256
    {
257
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
258
        // @codeCoverageIgnoreStart
259
        return false;
260
        // @codeCoverageIgnoreEnd
261
      }
262
263
      if (!mysqli_data_seek($result, $row)) {
264
        trigger_error(
265
          sprintf(
266
            'mysql_result(): Unable to jump to row %d on MySQL result index %s',
267
            $row,
268
            spl_object_hash($result)
269
          ),
270
          E_USER_WARNING
271
        );
272
        // @codeCoverageIgnoreStart
273
        return false;
274
        // @codeCoverageIgnoreEnd
275
      }
276
277
      $found = true;
278
      if (strpos($field, '.') !== false) {
279
        list($table, $name) = explode('.', $field);
280
        $i = 0;
281
        $found = false;
282
        mysqli_field_seek($result, 0);
283
        while ($column = mysqli_fetch_field($result)) {
284
          if ($column->table === $table && $column->name === $name) {
285
            $field = $i;
286
            $found = true;
287
            break;
288
          }
289
          $i++;
290
        }
291
      }
292
293
      $row = mysql_fetch_array($result);
294
      if ($found && array_key_exists($field, $row)) {
295
        return $row[$field];
296
      }
297
298
      trigger_error(
299
        sprintf(
300
          '%s(): %s not found in MySQL result index %s',
301
          __FUNCTION__,
302
          $field,
303
          spl_object_hash($result)
304
        ),
305
        E_USER_WARNING
306
      );
307
      // @codeCoverageIgnoreStart
308
      return false;
309
      // @codeCoverageIgnoreEnd
310
    }
311
312
    function mysql_num_rows($result)
313
    {
314
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
315
        // @codeCoverageIgnoreStart
316
        return false;
317
        // @codeCoverageIgnoreEnd
318
      }
319
320
      $previous = error_reporting(0);
321
      $rows = mysqli_num_rows($result);
322
      error_reporting($previous);
323
324
      return $rows;
325
    }
326
327
    function mysql_num_fields($result)
328
    {
329
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
330
        // @codeCoverageIgnoreStart
331
        return false;
332
        // @codeCoverageIgnoreEnd
333
      }
334
      return mysqli_num_fields($result);
335
    }
336
337
    function mysql_fetch_row($result)
338
    {
339
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
340
        // @codeCoverageIgnoreStart
341
        return false;
342
        // @codeCoverageIgnoreEnd
343
      }
344
      return mysqli_fetch_row($result) ?: false;
345
    }
346
    /**
347
     * Fetch result as assoc array
348
     *
349
     * @param [type] $result
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
350
     * @param [type] $resultType
351
     * @return array|null
352
     */
353
    function mysql_fetch_array($result, $resultType = MYSQL_BOTH)
0 ignored issues
show
The constant MYSQL_BOTH has been deprecated: 5.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

353
    function mysql_fetch_array($result, $resultType = /** @scrutinizer ignore-deprecated */ MYSQL_BOTH)
Loading history...
354
    {
355
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
356
        // @codeCoverageIgnoreStart
357
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array|null.
Loading history...
358
        // @codeCoverageIgnoreEnd
359
      }
360
      return mysqli_fetch_array($result, $resultType) ?: false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return mysqli_fetch_arra..., $resultType) ?: false also could return the type false|null which is incompatible with the documented return type array|null.
Loading history...
361
    }
362
363
    /**
364
     * Fetch a result row as assoc array
365
     * @inheritDoc mysqli_fetch_assoc
366
     * @param [type] $result
0 ignored issues
show
Documentation Bug introduced by
The doc comment [type] at position 0 could not be parsed: Unknown type name '[' at position 0 in [type].
Loading history...
367
     * @return array|null
368
     */
369
    function mysql_fetch_assoc($result) /* : array|null */
370
    {
371
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
372
        // @codeCoverageIgnoreStart
373
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type array|null.
Loading history...
374
        // @codeCoverageIgnoreEnd
375
      }
376
377
      return mysqli_fetch_assoc($result) ?: false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return mysqli_fetch_assoc($result) ?: false could also return false which is incompatible with the documented return type array|null. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
378
    }
379
380
    function mysql_fetch_object($result, $class = null, array $params = array()) /* : object|null */
381
    {
382
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
383
        // @codeCoverageIgnoreStart
384
        return false;
385
        // @codeCoverageIgnoreEnd
386
      }
387
388
      if ($class === null) {
389
        $object = mysqli_fetch_object($result);
390
      } else {
391
        $object = mysqli_fetch_object($result, $class, $params);
392
      }
393
394
      return $object ?: false;
395
    }
396
397
    function mysql_data_seek($result, $offset)
398
    {
399
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
400
        // @codeCoverageIgnoreStart
401
        return false;
402
        // @codeCoverageIgnoreEnd
403
      }
404
      return mysqli_data_seek($result, $offset);
405
    }
406
407
    function mysql_fetch_lengths($result) /* : array|*/
408
    {
409
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
410
        // @codeCoverageIgnoreStart
411
        return false;
412
        // @codeCoverageIgnoreEnd
413
      }
414
      return mysqli_fetch_lengths($result);
415
    }
416
417
    function mysql_fetch_field($result) /* : object|*/
418
    {
419
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
420
        // @codeCoverageIgnoreStart
421
        return false;
422
        // @codeCoverageIgnoreEnd
423
      }
424
      return mysqli_fetch_field($result);
425
    }
426
427
    function mysql_field_seek($result, $field)
428
    {
429
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
430
        // @codeCoverageIgnoreStart
431
        return false;
432
        // @codeCoverageIgnoreEnd
433
      }
434
      return mysqli_field_seek($result, $field);
435
    }
436
437
    function mysql_free_result($result)
438
    {
439
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
440
        // @codeCoverageIgnoreStart
441
        return false;
442
        // @codeCoverageIgnoreEnd
443
      }
444
      return mysqli_free_result($result);
0 ignored issues
show
Are you sure the usage of mysqli_free_result($result) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
445
    }
446
447
    function mysql_field_name($result, $field)
448
    {
449
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
450
        // @codeCoverageIgnoreStart
451
        return false;
452
        // @codeCoverageIgnoreEnd
453
      }
454
      return \UniversalFramework\MySQL::mysqlFieldInfo($result, $field, 'name');
455
    }
456
457
    function mysql_field_table($result, $field)
458
    {
459
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
460
        // @codeCoverageIgnoreStart
461
        return false;
462
        // @codeCoverageIgnoreEnd
463
      }
464
      return \UniversalFramework\MySQL::mysqlFieldInfo($result, $field, 'table');
465
    }
466
467
    function mysql_field_len($result, $field)
468
    {
469
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
470
        // @codeCoverageIgnoreStart
471
        return false;
472
        // @codeCoverageIgnoreEnd
473
      }
474
      return \UniversalFramework\MySQL::mysqlFieldInfo($result, $field, 'length');
475
    }
476
477
    function mysql_field_type($result, $field)
478
    {
479
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
480
        // @codeCoverageIgnoreStart
481
        return false;
482
        // @codeCoverageIgnoreEnd
483
      }
484
      return \UniversalFramework\MySQL::mysqlFieldInfo($result, $field, 'type');
485
    }
486
487
    function mysql_field_flags($result, $field)
488
    {
489
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
490
        // @codeCoverageIgnoreStart
491
        return false;
492
        // @codeCoverageIgnoreEnd
493
      }
494
      return \UniversalFramework\MySQL::mysqlFieldInfo($result, $field, 'flags');
495
    }
496
497
    function mysql_escape_string($unescapedString)
498
    {
499
      if (\UniversalFramework\MySQL::$last_connection === null) {
500
        trigger_error(
501
          sprintf(
502
            '%s() is insecure; use mysql_real_escape_string() instead!',
503
            __FUNCTION__
504
          ),
505
          E_USER_NOTICE
506
        );
507
508
        return \UniversalFramework\MySQL::escapeString($unescapedString);
509
      }
510
      return mysql_real_escape_string($unescapedString, null);
511
    }
512
513
    function mysql_real_escape_string($unescapedString, \mysqli $link = null)
514
    {
515
      return mysqli_escape_string(\UniversalFramework\MySQL::getConnection($link), $unescapedString);
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_escape_string() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

515
      return mysqli_escape_string(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link), $unescapedString);
Loading history...
516
    }
517
518
    function mysql_stat(\mysqli $link = null)
519
    {
520
      return mysqli_stat(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_stat() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

520
      return mysqli_stat(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
521
    }
522
523
    function mysql_thread_id(\mysqli $link = null)
524
    {
525
      return mysqli_thread_id(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_thread_id() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

525
      return mysqli_thread_id(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
526
    }
527
528
    function mysql_client_encoding(\mysqli $link = null)
529
    {
530
      return mysqli_character_set_name(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_character_set_name() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

530
      return mysqli_character_set_name(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
531
    }
532
533
    function mysql_ping(\mysqli $link = null)
534
    {
535
      return mysqli_ping(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_ping() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

535
      return mysqli_ping(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
536
    }
537
538
    function mysql_get_client_info(\mysqli $link = null)
539
    {
540
      return mysqli_get_client_info(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_get_client_info() does only seem to accept mysqli|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

540
      return mysqli_get_client_info(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
541
    }
542
543
    function mysql_get_host_info(\mysqli $link = null)
544
    {
545
      return mysqli_get_host_info(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_get_host_info() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

545
      return mysqli_get_host_info(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
546
    }
547
548
    function mysql_get_proto_info(\mysqli $link = null)
549
    {
550
      return mysqli_get_proto_info(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_get_proto_info() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

550
      return mysqli_get_proto_info(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
551
    }
552
553
    function mysql_get_server_info(\mysqli $link = null)
554
    {
555
      return mysqli_get_server_info(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_get_server_info() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

555
      return mysqli_get_server_info(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
556
    }
557
558
    function mysql_info(\mysqli $link = null)
559
    {
560
      return mysqli_info(\UniversalFramework\MySQL::getConnection($link));
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_info() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

560
      return mysqli_info(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link));
Loading history...
561
    }
562
563
    function mysql_set_charset($charset, \mysqli $link = null)
564
    {
565
      return mysqli_set_charset(\UniversalFramework\MySQL::getConnection($link), $charset);
0 ignored issues
show
It seems like UniversalFramework\MySQL::getConnection($link) can also be of type false; however, parameter $mysql of mysqli_set_charset() does only seem to accept mysqli, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

565
      return mysqli_set_charset(/** @scrutinizer ignore-type */ \UniversalFramework\MySQL::getConnection($link), $charset);
Loading history...
566
    }
567
568
    function mysql_db_name($result, $row, $field = 0)
569
    {
570
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
571
        // @codeCoverageIgnoreStart
572
        return false;
573
        // @codeCoverageIgnoreEnd
574
      }
575
576
      // Alias as per https://github.com/php/php-src/blob/PHP-5.6/ext/mysql/php_mysql.c#L319
577
      return mysql_result($result, $row, $field);
578
    }
579
580
    function mysql_tablename($result, $row)
581
    {
582
      if (!\UniversalFramework\MySQL::checkValidResult($result, __FUNCTION__)) {
583
        // @codeCoverageIgnoreStart
584
        return false;
585
        // @codeCoverageIgnoreEnd
586
      }
587
588
      // Alias as per http://lxr.php.net/xref/PHP_5_6/ext/mysql/php_mysql.c#321
589
      return mysql_result($result, $row, 'Table');
590
    }
591
592
    /* Aliases */
593
594
    function mysql_fieldname($result, $field)
595
    {
596
      return mysql_field_name($result, $field);
597
    }
598
599
    function mysql_fieldtable($result, $field)
600
    {
601
      return mysql_field_table($result, $field);
602
    }
603
604
    function mysql_fieldlen($result, $field)
605
    {
606
      return mysql_field_len($result, $field);
607
    }
608
609
    function mysql_fieldtype($result, $field)
610
    {
611
      return mysql_field_type($result, $field);
612
    }
613
614
    function mysql_fieldflags($result, $field)
615
    {
616
      return mysql_field_flags($result, $field);
617
    }
618
619
    function mysql_selectdb($databaseName, $link = null)
620
    {
621
      return mysql_select_db($databaseName, $link);
622
    }
623
624
    function mysql_freeresult($result)
625
    {
626
      return mysql_free_result($result);
627
    }
628
629
    function mysql_numfields($result)
630
    {
631
      return mysql_num_fields($result);
632
    }
633
634
    function mysql_numrows($result)
635
    {
636
      return mysql_num_rows($result);
637
    }
638
639
    function mysql_listdbs($link)
640
    {
641
      return mysql_list_dbs($link);
642
    }
643
644
    function mysql_listtables($databaseName, $link = null)
645
    {
646
      return mysql_list_tables($databaseName, $link);
647
    }
648
649
    function mysql_listfields($databaseName, $tableName, $link = null)
650
    {
651
      return mysql_list_fields($databaseName, $tableName, $link);
652
    }
653
654
    function mysql_dbname($result, $row, $field = 0)
655
    {
656
      return mysql_db_name($result, $row, $field);
657
    }
658
659
    function mysql_table_name($result, $row)
660
    {
661
      return mysql_tablename($result, $row);
662
    }
663
  }
664
}
665
666
namespace UniversalFramework {
667
668
  use mysqli;
669
670
  class MySQL
671
  {
672
    public static $last_connection = null;
673
    public static $connections = array();
674
675
    function __construct(mysqli $sql)
676
    {
677
      static::$last_connection = $sql;
678
    }
679
680
    /**
681
     * Get mysqli intances
682
     *
683
     * @param mysqli $link
684
     * @param function $func
0 ignored issues
show
The type UniversalFramework\function was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
685
     * @return false|mysqli
686
     */
687
    public static function getConnection($link = null, $func = null)
688
    {
689
      if ($link !== null) {
690
        static::$last_connection = $link;
691
        return $link;
692
      }
693
694
      if (static::$last_connection === null) {
695
        $err = 'A link to the server could not be established';
696
        if ($func !== null) {
697
          $err = $func . '(): no MySQL-Link resource supplied';
698
        }
699
        trigger_error($err, E_USER_WARNING);
700
        return false;
701
      }
702
703
      return static::$last_connection;
704
    }
705
706
    public static function mysqlFieldInfo(\mysqli_result $result, $field, $what)
707
    {
708
      try {
709
        $field = mysqli_fetch_field_direct($result, $field);
710
      } catch (\Exception $e) {
711
        trigger_error(
712
          sprintf(
713
            'mysql_field_%s(): Field %d is invalid for MySQL result index %s',
714
            ($what !== 'length') ? $what : 'len',
715
            $field,
0 ignored issues
show
$field of type object is incompatible with the type double|integer|string expected by parameter $values of sprintf(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

715
            /** @scrutinizer ignore-type */ $field,
Loading history...
716
            spl_object_hash($result)
717
          ),
718
          E_USER_WARNING
719
        );
720
        // @codeCoverageIgnoreStart
721
        // PHPUnit turns the warning into an exception, so this never runs
722
        return false;
723
        // @codeCoverageIgnoreEnd
724
      }
725
726
      if ($what === 'type') {
727
        return static::getFieldType($field->type);
728
      }
729
730
      if ($what === 'flags') {
731
        return static::getFieldFlags($field->flags);
732
      }
733
734
      if (isset($field->{$what})) {
735
        return $field->{$what};
736
      }
737
738
      return false;
739
    }
740
741
    public static function checkValidResult($result, $function)
742
    {
743
      if (!($result instanceof \mysqli_result)) {
744
        if ($function !== 'mysql_fetch_object') {
745
          trigger_error(
746
            $function . '() expects parameter 1 to be resource, ' . strtolower(gettype($result)) . ' given',
747
            E_USER_WARNING
748
          );
749
        }
750
751
        if ($function === 'mysql_fetch_object') {
752
          trigger_error(
753
            $function . '(): supplied argument is not a valid MySQL result resource',
754
            E_USER_WARNING
755
          );
756
        }
757
        return false;
758
      }
759
760
      return true;
761
    }
762
763
    public static function escapeString($unescapedString)
764
    {
765
      $escapedString = '';
766
      for ($i = 0, $max = strlen($unescapedString); $i < $max; $i++) {
767
        $escapedString .= self::escapeChar($unescapedString[$i]);
768
      }
769
770
      return $escapedString;
771
    }
772
773
    protected static function getFieldFlags($what)
774
    {
775
      // Order of flags taken from http://lxr.php.net/xref/PHP_5_6/ext/mysql/php_mysql.c#2507
776
      $flags = array(
777
        MYSQLI_NOT_NULL_FLAG => 'not_null',
778
        MYSQLI_PRI_KEY_FLAG => 'primary_key',
779
        MYSQLI_UNIQUE_KEY_FLAG => 'unique_key',
780
        MYSQLI_MULTIPLE_KEY_FLAG => 'multiple_key',
781
        MYSQLI_BLOB_FLAG => 'blob',
782
        MYSQLI_UNSIGNED_FLAG => 'unsigned',
783
        MYSQLI_ZEROFILL_FLAG => 'zerofill',
784
        MYSQLI_BINARY_FLAG => 'binary',
785
        MYSQLI_ENUM_FLAG => 'enum',
786
        MYSQLI_SET_FLAG => 'set',
787
        MYSQLI_AUTO_INCREMENT_FLAG => 'auto_increment',
788
        MYSQLI_TIMESTAMP_FLAG => 'timestamp',
789
      );
790
791
      $fieldFlags = array();
792
      foreach ($flags as $flag => $value) {
793
        if ($what & $flag) {
794
          $fieldFlags[] = $value;
795
        }
796
      }
797
798
      return implode(' ', $fieldFlags);
799
    }
800
801
    protected static function getFieldType($what)
802
    {
803
      $types = array(
804
        MYSQLI_TYPE_STRING => 'string',
805
        MYSQLI_TYPE_VAR_STRING => 'string',
806
        MYSQLI_TYPE_ENUM => 'string',
807
        MYSQLI_TYPE_SET => 'string',
808
809
        MYSQLI_TYPE_LONG => 'int',
810
        MYSQLI_TYPE_TINY => 'int',
811
        MYSQLI_TYPE_SHORT => 'int',
812
        MYSQLI_TYPE_INT24 => 'int',
813
        MYSQLI_TYPE_CHAR => 'int',
814
        MYSQLI_TYPE_LONGLONG => 'int',
815
816
        MYSQLI_TYPE_DECIMAL => 'real',
817
        MYSQLI_TYPE_FLOAT => 'real',
818
        MYSQLI_TYPE_DOUBLE => 'real',
819
        MYSQLI_TYPE_NEWDECIMAL => 'real',
820
821
        MYSQLI_TYPE_TINY_BLOB => 'blob',
822
        MYSQLI_TYPE_MEDIUM_BLOB => 'blob',
823
        MYSQLI_TYPE_LONG_BLOB => 'blob',
824
        MYSQLI_TYPE_BLOB => 'blob',
825
826
        MYSQLI_TYPE_NEWDATE => 'date',
827
        MYSQLI_TYPE_DATE => 'date',
828
        MYSQLI_TYPE_TIME => 'time',
829
        MYSQLI_TYPE_YEAR => 'year',
830
        MYSQLI_TYPE_DATETIME => 'datetime',
831
        MYSQLI_TYPE_TIMESTAMP => 'timestamp',
832
833
        MYSQLI_TYPE_NULL => 'null',
834
835
        MYSQLI_TYPE_GEOMETRY => 'geometry',
836
      );
837
838
      return isset($types[$what]) ? $types[$what] : 'unknown';
839
    }
840
841
    protected static function escapeChar($char)
842
    {
843
      switch ($char) {
844
        case "\0":
845
          $esc = "\\0";
846
          break;
847
        case "\n":
848
          $esc = "\\n";
849
          break;
850
        case "\r":
851
          $esc = "\\r";
852
          break;
853
        case '\\':
854
        case '\'':
855
        case '"':
856
          $esc = "\\{$char}";
857
          break;
858
        case "\032":
859
          $esc = "\\Z";
860
          break;
861
        default:
862
          $esc = $char;
863
          break;
864
      }
865
866
      return $esc;
867
    }
868
  }
869
}
870