Completed
Push — work-fleets ( 4ec5b3...fe2ede )
by SuperNova.WS
10:06
created

debug.php ➔ debug()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
crap 2
1
<?php
2
/**
3
 * Some helpers to sweeten dev's life
4
 */
5
6
use \DBAL\DbTransaction;
7
8
/*
9
 * debug.php ::  Clase Debug, maneja reporte de eventos
10
 *
11
 * V4.0 copyright 2010-2011 by Gorlum for http://supernova.ws
12
 *  [!] Merged `errors` to `logs`
13
 *  [+] Now debugger can work with database detached. All messages would be dumped to page
14
 *  [+] Now `logs` has both human-readable and machine-readable fields
15
 *
16
 * V3.0 copyright 2010 by Gorlum for http://supernova.ws
17
 *  [+] Full rewrtie & optimize
18
 *  [*] Now there is fallback procedure if no link to db detected
19
 *
20
 * V2.0 copyright 2010 by Gorlum for http://supernova.ws
21
 *  [*] Now error also contains backtrace - to see exact way problem comes
22
 *  [*] New method 'warning' sends message to dedicated SQL-table for non-errors
23
 *
24
 * V1.0 Created by Perberos. All rights reversed (C) 2006
25
 *
26
 *  Experiment code!!!
27
 *
28
 * vamos a experimentar >:)
29
 * le veo futuro a las classes, ayudaria mucho a tener un codigo mas ordenado...
30
 * que esperabas!!! soy newbie!!! D':<
31
*/
32
33
defined('INSIDE') || die();
34
35
if(php_sapi_name() == "cli") {
36
  // In cli-mode
37
  define('__DEBUG_CRLF', "\r\n");
38
  define('__DEBUG_LINE', '-------------------------------------------------' . __DEBUG_CRLF);
39
} else {
40
  // Not in cli-mode
41
  define('__DEBUG_CRLF', '<br />');
42
  define('__DEBUG_LINE', '<hr />');
43
}
44
45
46
class debug {
47
  var $log, $numqueries;
48
  var $log_array;
49
50
  private $log_file_handler = null;
51
52
  public function log_file($message, $ident_change = 0) {
53
    static $ident = 0;
54
55
    if(!defined('SN_DEBUG_LOG')) {
56
      return;
57
    }
58
59
    if($this->log_file_handler === null) {
60
      $this->log_file_handler = @fopen(SN_ROOT_PHYSICAL . '/.logs/supernova.log', 'a+');
61
      @fwrite($this->log_file_handler, "\r\n\r\n");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
62
    }
63
    $ident_change < 0 ? $ident += $ident_change * 2 : false;
64
    if($this->log_file_handler) {
65
      @fwrite($this->log_file_handler, date(FMT_DATE_TIME_SQL, time()) . str_repeat(' ', $ident + 1) . $message . "\r\n");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
66
    }
67
    $ident_change > 0 ? $ident += $ident_change * 2 : false;
68
  }
69
70
  public function debug() {
71
    $this->vars = $this->log = '';
0 ignored issues
show
Bug introduced by
The property vars does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
72
    $this->numqueries = 0;
73
  }
74
75
  public function add($mes) {
76
    $this->log .= $mes;
77
    $this->numqueries++;
78
  }
79
80
  public function add_to_array($mes) {
81
    $this->log_array[] = $mes;
82
  }
83
84
  public function echo_log() {
85
    echo '<br><table><tr><td class=k colspan=4><a href="' . SN_ROOT_PHYSICAL . "admin/settings.php\">Debug Log</a>:</td></tr>{$this->log}</table>";
86
    die();
87
  }
88
89
  public function compact_backtrace($backtrace, $long_comment = false) {
90
    static $exclude_functions = array('doquery', 'db_query', 'db_get_record_list', 'db_user_by_id', 'db_get_user_by_id');
91
92
    $result = array();
93
    $transaction_id = classSupernova::$db->getTransaction()->getNextQueryTransactionId();
94
    $result[] = "tID {$transaction_id}";
95
    foreach($backtrace as $a_trace) {
96
      if(in_array($a_trace['function'], $exclude_functions)) {
97
        continue;
98
      }
99
      $function =
100
        ($a_trace['type']
101
          ? ($a_trace['type'] == '->'
102
            ? "({$a_trace['class']})" . get_class($a_trace['object'])
103
            : $a_trace['class']
104
          ) . $a_trace['type']
105
          : ''
106
        ) . $a_trace['function'] . '()';
107
108
      $file = str_replace(SN_ROOT_PHYSICAL, '', str_replace('\\', '/', $a_trace['file']));
109
110
      // $result[] = "{$function} ({$a_trace['line']})'{$file}'";
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
111
      $result[] = "{$function} - '{$file}' Line {$a_trace['line']}";
112
113
      if(!$long_comment) {
114
        break;
115
      }
116
    }
117
118
119
    // $result = implode(',', $result);
0 ignored issues
show
Unused Code Comprehensibility introduced by
54% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
120
121
    return $result;
122
  }
123
124
  /**
125
   * @param mixed $dump
126
   * @param bool $force_base
127
   * @param bool $deadlock
128
   *
129
   * @return array|void
130
   */
131
  public function dump($dump = false, $force_base = false, $deadlock = false) {
132
    global $user, $planetrow;
133
134
    if($dump === false) {
135
      return;
136
    }
137
138
    $error_backtrace = array();
139
    $base_dump = false;
140
141
    if($force_base === true) {
142
      $base_dump = true;
143
    }
144
145
    if($dump === true) {
146
      $base_dump = true;
147
    } else {
148
      if(!is_array($dump)) {
149
        $dump = array('var' => $dump);
150
      }
151
152
      foreach($dump as $dump_var_name => $dump_var) {
153
        if($dump_var_name == 'base_dump') {
154
          $base_dump = $dump_var;
155
        } else {
156
          $error_backtrace[$dump_var_name] = $dump_var;
157
        }
158
      }
159
    }
160
161
    if($deadlock && ($q = db_fetch(classSupernova::$db->mysql_get_innodb_status()))) {
0 ignored issues
show
Bug introduced by
\classSupernova::$db->mysql_get_innodb_status() cannot be passed to db_fetch() as the parameter $query expects a reference.
Loading history...
162
      $error_backtrace['deadlock'] = explode("\n", $q['Status']);
163
      $error_backtrace['locks'] = classSupernova::$gc->snCache->getLocks();
0 ignored issues
show
Bug introduced by
The method getLocks does only exist in SnCache, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
164
      $error_backtrace['cSN_data'] = classSupernova::$gc->snCache->getData();
0 ignored issues
show
Bug introduced by
The method getData does only exist in SnCache, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
165
      foreach($error_backtrace['cSN_data'] as &$location) {
166
        foreach($location as $location_id => &$location_data) {
167
          $location_data = isset($location_data['username']) ? $location_data['username'] :
168
            (isset($location_data['name']) ? $location_data['name'] : $location_id);
169
        }
170
      }
171
      $error_backtrace['cSN_queries'] = classSupernova::$gc->snCache->getQueries();
0 ignored issues
show
Bug introduced by
The method getQueries does only exist in SnCache, but not in Closure.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
172
    }
173
174
    if($base_dump) {
175
      if(is_array($this->log_array) && count($this->log_array) > 0) {
176
        foreach($this->log_array as $log) {
177
          $error_backtrace['queries'][] = $log;
178
        }
179
      }
180
181
      $error_backtrace['backtrace'] = debug_backtrace();
182
      unset($error_backtrace['backtrace'][1]);
183
      unset($error_backtrace['backtrace'][0]);
184
      $error_backtrace['$_GET'] = $_GET;
185
      $error_backtrace['$_POST'] = $_POST;
186
      $error_backtrace['$_REQUEST'] = $_REQUEST;
187
      $error_backtrace['$_COOKIE'] = $_COOKIE;
188
      $error_backtrace['$_SESSION'] = $_SESSION;
189
      $error_backtrace['$_SERVER'] = $_SERVER;
190
      $error_backtrace['user'] = $user;
191
      $error_backtrace['planetrow'] = $planetrow;
192
    }
193
194
    return $error_backtrace;
195
  }
196
197
  public function error_fatal($die_message, $details = 'There is a fatal error on page') {
0 ignored issues
show
Unused Code introduced by
The parameter $details is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
198
    // TODO - Записывать детали ошибки в лог-файл
199
    die($die_message);
200
  }
201
202
  public function error($message = 'There is a error on page', $title = 'Internal Error', $error_code = 500, $dump = true) {
203
    global $sys_stop_log_hit, $sys_log_disabled, $user;
204
205
    if(empty(classSupernova::$db->connected)) {
206
      // TODO - писать ошибку в файл
207
      die('SQL server currently unavailable. Please contact Administration...');
208
    }
209
210
    sn_db_transaction_rollback();
211
212
    if(classSupernova::$config->debug == 1) {
213
      echo "<h2>{$title}</h2><br><font color=red>{$message}</font><br><hr>";
214
      echo "<table>{$this->log}</table>";
215
    }
216
217
    $fatal_error = 'Fatal error: cannot write to `logs` table. Please contact Administration...';
218
219
    $error_text = db_escape($message);
220
    $error_backtrace = $this->dump($dump, true, strpos($message, 'Deadlock') !== false);
221
222
    $userId = empty($user['id']) ? 0 : $user['id'];
223
224
    if(!$sys_log_disabled) {
225
      $query = "INSERT INTO `{{logs}}` SET
226
        `log_time` = '" . time() . "', `log_code` = '" . db_escape($error_code) . "', `log_sender` = '" . db_escape($userId) . "',
227
        `log_username` = '" . db_escape($user['user_name']) . "', `log_title` = '" . db_escape($title) . "',  `log_text` = '" . db_escape($message) . "',
228
        `log_page` = '" . db_escape(strpos($_SERVER['SCRIPT_NAME'], SN_ROOT_RELATIVE) === false ? $_SERVER['SCRIPT_NAME'] : substr($_SERVER['SCRIPT_NAME'], strlen(SN_ROOT_RELATIVE))) . "'" .
229
//        ($error_backtrace ? ", `log_dump` = '" . db_escape(serialize($error_backtrace)) . "'" : '') . ";";
0 ignored issues
show
Unused Code Comprehensibility introduced by
49% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
230
      ", `log_dump` = '" . ($error_backtrace ? db_escape(serialize($error_backtrace)) : '') . "'" . ";";
231
      classSupernova::$db->doSql($query, true) or die($fatal_error . classSupernova::$db->db_error());
232
233
      $message = "Пожалуйста, свяжитесь с админом, если ошибка повторится. Ошибка №: <b>" . classSupernova::$db->db_insert_id() . "</b>";
234
235
      $sys_stop_log_hit = true;
236
      $sys_log_disabled = true;
237
      !function_exists('message') ? die($message) : message($message, 'Ошибка', '', 0, false);
238
    } else {
239
//        // TODO Здесь надо писать в файло
240
      ob_start();
241
      print("<hr>User ID {$user['id']} raised error code {$error_code} titled '{$title}' with text '{$error_text}' on page {$_SERVER['SCRIPT_NAME']}");
242
243
      foreach($error_backtrace as $name => $value) {
0 ignored issues
show
Bug introduced by
The expression $error_backtrace of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
244
        print(__DEBUG_LINE);
245
        pdump($value, $name);
246
      }
247
      ob_end_flush();
248
      die();
249
    }
250
  }
251
252
  /**
253
   * @param        $message
254
   * @param string $title
255
   * @param int    $log_code
256
   * @param mixed $dump
257
   */
258
  public function warning($message, $title = 'System Message', $log_code = 300, $dump = false) {
259
    global $user, $sys_log_disabled;
260
261
    if(empty(classSupernova::$db->connected)) {
262
      // TODO - писать ошибку в файл
263
      die('SQL server currently unavailable. Please contact Administration...');
264
    }
265
266
    $error_backtrace = $this->dump($dump, false);
267
268
    $userId = empty($user['id']) ? 0 : $user['id'];
269
270
    if(!$sys_log_disabled) {
271
      $query = "INSERT INTO `{{logs}}` SET
272
        `log_time` = '" . time() . "', `log_code` = '" . db_escape($log_code) . "', `log_sender` = '" . db_escape($userId) . "',
273
        `log_username` = '" . db_escape($user['user_name']) . "', `log_title` = '" . db_escape($title) . "',  `log_text` = '" . db_escape($message) . "',
274
        `log_page` = '" . db_escape(strpos($_SERVER['SCRIPT_NAME'], SN_ROOT_RELATIVE) === false ? $_SERVER['SCRIPT_NAME'] : substr($_SERVER['SCRIPT_NAME'], strlen(SN_ROOT_RELATIVE))) . "'" .
275
        ", `log_dump` = '" . ($error_backtrace ? db_escape(serialize($error_backtrace)) : '') . "'" . ";";
276
      classSupernova::$db->doSql($query, true);
277
    } else {
278
//        // TODO Здесь надо писать в файло
279
      print("<hr>User ID {$user['id']} made log entry with code {$log_code} titled '{$title}' with text '{$message}' on page {$_SERVER['SCRIPT_NAME']}");
280
    }
281
  }
282
}
283
284
// Copyright (c) 2009-2010 Gorlum for http://supernova.ws
285
// Dump variables nicer then var_dump()
286
287
function dump($value, $varname = null, $level = 0, $dumper = '') {
288
  if(isset($varname)) {
289
    $varname .= " = ";
290
  }
291
292
  if($level == -1) {
293
    $trans[' '] = '&there4;';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$trans was never initialized. Although not strictly required by PHP, it is generally a good practice to add $trans = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
294
    $trans["\t"] = '&rArr;';
295
    $trans["\n"] = '&para;;';
296
    $trans["\r"] = '&lArr;';
297
    $trans["\0"] = '&oplus;';
298
299
    return strtr(htmlspecialchars($value), $trans);
300
  }
301
  if($level == 0) {
302
//    $dumper = '<pre>' . mt_rand(10, 99) . '|' . $varname;
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
303
    $dumper = mt_rand(10, 99) . '|' . $varname;
304
  }
305
306
  $type = gettype($value);
307
  $dumper .= $type;
308
309
  if($type == TYPE_STRING) {
310
    $dumper .= '(' . strlen($value) . ')';
311
    $value = dump($value, '', -1);
312
  } elseif($type == TYPE_BOOLEAN) {
313
    $value = ($value ? 'true' : 'false');
314
  } elseif($type == 'object') {
315
    $props = get_class_vars(get_class($value));
316
    $dumper .= '(' . count($props) . ') <u>' . get_class($value) . '</u>';
317
    foreach($props as $key => $val) {
318
      $dumper .= "\n" . str_repeat("\t", $level + 1) . $key . ' => ';
319
      $dumper .= dump($value->$key, '', $level + 1);
320
    }
321
    $value = '';
322 View Code Duplication
  } elseif($type == TYPE_ARRAY) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
323
    $dumper .= '(' . count($value) . ')';
324
    foreach($value as $key => $val) {
325
      $dumper .= "\n" . str_repeat("\t", $level + 1) . dump($key, '', -1) . ' => ';
326
      $dumper .= dump($val, '', $level + 1);
327
    }
328
    $value = '';
329
  }
330
  $dumper .= " <b>$value</b>";
331
//  if($level == 0) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
44% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
332
//    $dumper .= '</pre>';
333
//  }
334
335
  return $dumper;
336
}
337
338
function pdump($value, $varname = null) {
339
  $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
340
//  print_rr($backtrace);
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
341
//  $backtrace = $backtrace[1];
342
343
  $caller = '';
344
  if(defined('SN_DEBUG_PDUMP_CALLER') && SN_DEBUG_PDUMP_CALLER) {
345
    $caller = (!empty($backtrace[1]['class']) ? $backtrace[1]['class'] : '') .
346
      (!empty($backtrace[1]['type']) ? $backtrace[1]['type'] : '') .
347
      $backtrace[1]['function'] .
348
      (!empty($backtrace[0]['file'])
349
        ? (
350
          ' (' . substr($backtrace[0]['file'], SN_ROOT_PHYSICAL_STR_LEN) .
351
          (!empty($backtrace[0]['line']) ? ':' . $backtrace[0]['line'] : '') .
352
          ')'
353
        )
354
        : ''
355
      );
356
    $caller = "\r\n" . $caller;
357
  }
358
359
  print('<pre style="text-align: left; background-color: #111111; color: #0A0; font-family: Courier, monospace !important; padding: 1em 0; font-weight: 800; font-size: 14px;">' .
0 ignored issues
show
Security Cross-Site Scripting introduced by
'<pre style="text-align:...e) . $caller . '</pre>' can contain request data and is used in output context(s) leading to a potential security vulnerability.

5 paths for user data to reach this point

  1. Path: Read from $_GET, and $error_backtrace is assigned in classes/debug.php on line 184
  1. Read from $_GET, and $error_backtrace is assigned
    in classes/debug.php on line 184
  2. $error_backtrace is assigned
    in classes/debug.php on line 185
  3. $error_backtrace is assigned
    in classes/debug.php on line 186
  4. $error_backtrace is assigned
    in classes/debug.php on line 187
  5. $error_backtrace is assigned
    in classes/debug.php on line 188
  6. $error_backtrace is assigned
    in classes/debug.php on line 189
  7. $error_backtrace is assigned
    in classes/debug.php on line 190
  8. $error_backtrace is assigned
    in classes/debug.php on line 191
  9. debug::dump() returns tainted data, and $error_backtrace is assigned
    in classes/debug.php on line 220
  10. $name is assigned
    in classes/debug.php on line 243
  11. $name is passed to pdump()
    in classes/debug.php on line 245
  2. Path: Read from $_POST, and $error_backtrace is assigned in classes/debug.php on line 185
  1. Read from $_POST, and $error_backtrace is assigned
    in classes/debug.php on line 185
  2. $error_backtrace is assigned
    in classes/debug.php on line 186
  3. $error_backtrace is assigned
    in classes/debug.php on line 187
  4. $error_backtrace is assigned
    in classes/debug.php on line 188
  5. $error_backtrace is assigned
    in classes/debug.php on line 189
  6. $error_backtrace is assigned
    in classes/debug.php on line 190
  7. $error_backtrace is assigned
    in classes/debug.php on line 191
  8. debug::dump() returns tainted data, and $error_backtrace is assigned
    in classes/debug.php on line 220
  9. $name is assigned
    in classes/debug.php on line 243
  10. $name is passed to pdump()
    in classes/debug.php on line 245
  3. Path: Read from $_REQUEST, and $error_backtrace is assigned in classes/debug.php on line 186
  1. Read from $_REQUEST, and $error_backtrace is assigned
    in classes/debug.php on line 186
  2. $error_backtrace is assigned
    in classes/debug.php on line 187
  3. $error_backtrace is assigned
    in classes/debug.php on line 188
  4. $error_backtrace is assigned
    in classes/debug.php on line 189
  5. $error_backtrace is assigned
    in classes/debug.php on line 190
  6. $error_backtrace is assigned
    in classes/debug.php on line 191
  7. debug::dump() returns tainted data, and $error_backtrace is assigned
    in classes/debug.php on line 220
  8. $name is assigned
    in classes/debug.php on line 243
  9. $name is passed to pdump()
    in classes/debug.php on line 245
  4. Path: Read from $_COOKIE, and $error_backtrace is assigned in classes/debug.php on line 187
  1. Read from $_COOKIE, and $error_backtrace is assigned
    in classes/debug.php on line 187
  2. $error_backtrace is assigned
    in classes/debug.php on line 188
  3. $error_backtrace is assigned
    in classes/debug.php on line 189
  4. $error_backtrace is assigned
    in classes/debug.php on line 190
  5. $error_backtrace is assigned
    in classes/debug.php on line 191
  6. debug::dump() returns tainted data, and $error_backtrace is assigned
    in classes/debug.php on line 220
  7. $name is assigned
    in classes/debug.php on line 243
  8. $name is passed to pdump()
    in classes/debug.php on line 245
  5. Path: Read from $_SERVER, and $error_backtrace is assigned in classes/debug.php on line 189
  1. Read from $_SERVER, and $error_backtrace is assigned
    in classes/debug.php on line 189
  2. $error_backtrace is assigned
    in classes/debug.php on line 190
  3. $error_backtrace is assigned
    in classes/debug.php on line 191
  4. debug::dump() returns tainted data, and $error_backtrace is assigned
    in classes/debug.php on line 220
  5. $name is assigned
    in classes/debug.php on line 243
  6. $name is passed to pdump()
    in classes/debug.php on line 245

Preventing Cross-Site-Scripting Attacks

Cross-Site-Scripting allows an attacker to inject malicious code into your website - in particular Javascript code, and have that code executed with the privileges of a visiting user. This can be used to obtain data, or perform actions on behalf of that visiting user.

In order to prevent this, make sure to escape all user-provided data:

// for HTML
$sanitized = htmlentities($tainted, ENT_QUOTES);

// for URLs
$sanitized = urlencode($tainted);

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
360
    dump($value, $varname) .
361
    $caller .
362
    '</pre>'
363
  );
364
}
365
366
function debug($value, $varname = null) {
367
  pdump($value, $varname);
368
}
369
370
function pr($prePrint = false) {
371
  if($prePrint) {
372
    print(__DEBUG_CRLF);
373
  }
374
  print(mt_rand() . __DEBUG_CRLF);
375
}
376
377
function pc($prePrint = false) {
378
  global $_PRINT_COUNT_VALUE;
379
  $_PRINT_COUNT_VALUE++;
380
381
  if($prePrint) {
382
    print(__DEBUG_CRLF);
383
  }
384
  print($_PRINT_COUNT_VALUE . __DEBUG_CRLF);
385
}
386
387
function prep($message) {
388
  print('<pre>' . $message . '</pre>');
389
}
390
391
function backtrace_no_arg() {
392
  $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
393
  array_shift($trace);
394
395
  return $trace;
396
}
397
398
function pvar_dump($expression) {
399
  print('<pre style="text-align: left; background-color: #111111; color: #0A0; font-family: Courier, monospace !important; padding: 1em 0; font-weight: 800; font-size: 14px;">');
400
  var_dump($expression);
401
  print('</pre>');
402
}
403
404
/**
405
 * Smart die() implementation that knew where it's grave
406
 *
407
 * @param string $message
408
 * @param int $level - shift backtrace to X levels back
409
 */
410
function pdie($message = '', $level = 0) {
411
  $backtrace = debug_backtrace();
412
  for($i = 0; $i < $level; $i++) {
413
    array_pop($backtrace);
414
  }
415
416
  die(__DEBUG_LINE . ($message ? $message . ' @ ' : '') . $backtrace[0]['file'] . ':' . $backtrace[0]['line']);
417
}
418