Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 318 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
| get_usable_memory | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
90 | |||
| sanitize_data_mssql | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
| sanitize_data_oracle | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
| sanitize_data_generic | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
| fgetd | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
| fgetd_seekless | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
56 | |||
| acp_database | |
0.00% |
0 / 241 |
|
0.00% |
0 / 4 |
4290 | |
0.00% |
0 / 1 |
| main | |
0.00% |
0 / 211 |
|
0.00% |
0 / 1 |
2970 | |||
| get_backup_file | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
20 | |||
| get_file_list | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
20 | |||
| get_supported_extensions | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * |
| 4 | * This file is part of the phpBB Forum Software package. |
| 5 | * |
| 6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
| 7 | * @license GNU General Public License, version 2 (GPL-2.0) |
| 8 | * |
| 9 | * For full copyright and license information, please see |
| 10 | * the docs/CREDITS.txt file. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | /** |
| 15 | * @ignore |
| 16 | */ |
| 17 | if (!defined('IN_PHPBB')) |
| 18 | { |
| 19 | exit; |
| 20 | } |
| 21 | |
| 22 | class acp_database |
| 23 | { |
| 24 | protected $db_tools; |
| 25 | protected $temp; |
| 26 | public $u_action; |
| 27 | public $page_title; |
| 28 | |
| 29 | function main($id, $mode) |
| 30 | { |
| 31 | global $cache, $db, $user, $template, $table_prefix, $request; |
| 32 | global $phpbb_root_path, $phpbb_container, $phpbb_log, $table_prefix; |
| 33 | |
| 34 | $this->db_tools = $phpbb_container->get('dbal.tools'); |
| 35 | $this->temp = $phpbb_container->get('filesystem.temp'); |
| 36 | /** @var \phpbb\storage\storage $storage */ |
| 37 | $storage = $phpbb_container->get('storage.backup'); |
| 38 | |
| 39 | $user->add_lang('acp/database'); |
| 40 | |
| 41 | $this->tpl_name = 'acp_database'; |
| 42 | $this->page_title = 'ACP_DATABASE'; |
| 43 | |
| 44 | $action = $request->variable('action', ''); |
| 45 | |
| 46 | $form_key = 'acp_database'; |
| 47 | add_form_key($form_key); |
| 48 | |
| 49 | $template->assign_vars(array( |
| 50 | 'MODE' => $mode |
| 51 | )); |
| 52 | |
| 53 | switch ($mode) |
| 54 | { |
| 55 | case 'backup': |
| 56 | |
| 57 | $this->page_title = 'ACP_BACKUP'; |
| 58 | |
| 59 | switch ($action) |
| 60 | { |
| 61 | case 'download': |
| 62 | $type = $request->variable('type', ''); |
| 63 | $table = array_intersect($this->db_tools->sql_list_tables(), $request->variable('table', array(''))); |
| 64 | $format = $request->variable('method', ''); |
| 65 | |
| 66 | if (!count($table)) |
| 67 | { |
| 68 | trigger_error($user->lang['TABLE_SELECT_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 69 | } |
| 70 | |
| 71 | if (!check_form_key($form_key)) |
| 72 | { |
| 73 | trigger_error($user->lang['FORM_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 74 | } |
| 75 | |
| 76 | @set_time_limit(1200); |
| 77 | @set_time_limit(0); |
| 78 | |
| 79 | $time = time(); |
| 80 | |
| 81 | $filename = 'backup_' . $time . '_' . unique_id(); |
| 82 | |
| 83 | try |
| 84 | { |
| 85 | /** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */ |
| 86 | $extractor = $phpbb_container->get('dbal.extractor'); |
| 87 | $extractor->init_extractor($format, $filename, $time, false, true); |
| 88 | |
| 89 | $extractor->write_start($table_prefix); |
| 90 | |
| 91 | foreach ($table as $table_name) |
| 92 | { |
| 93 | // Get the table structure |
| 94 | if ($type == 'full') |
| 95 | { |
| 96 | // Add table structure to the backup |
| 97 | // This method also add a "drop the table if exists" after trying to write the table structure |
| 98 | $extractor->write_table($table_name); |
| 99 | } |
| 100 | else |
| 101 | { |
| 102 | // Add command to empty table before write data on it |
| 103 | switch ($db->get_sql_layer()) |
| 104 | { |
| 105 | case 'sqlite3': |
| 106 | $extractor->flush('DELETE FROM ' . $table_name . ";\n"); |
| 107 | break; |
| 108 | |
| 109 | case 'mssql_odbc': |
| 110 | case 'mssqlnative': |
| 111 | $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n"); |
| 112 | break; |
| 113 | |
| 114 | case 'oracle': |
| 115 | $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n"); |
| 116 | break; |
| 117 | |
| 118 | default: |
| 119 | $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n"); |
| 120 | break; |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | // Only supported types are full and data, therefore always write the data |
| 125 | $extractor->write_data($table_name); |
| 126 | } |
| 127 | |
| 128 | $extractor->write_end(); |
| 129 | } |
| 130 | catch (\phpbb\exception\runtime_exception $e) |
| 131 | { |
| 132 | trigger_error($e->getMessage(), E_USER_ERROR); |
| 133 | } |
| 134 | |
| 135 | try |
| 136 | { |
| 137 | // Get file name |
| 138 | switch ($format) |
| 139 | { |
| 140 | case 'text': |
| 141 | $ext = '.sql'; |
| 142 | break; |
| 143 | |
| 144 | case 'bzip2': |
| 145 | $ext = '.sql.gz2'; |
| 146 | break; |
| 147 | |
| 148 | case 'gzip': |
| 149 | $ext = '.sql.gz'; |
| 150 | break; |
| 151 | } |
| 152 | |
| 153 | $file = $filename . $ext; |
| 154 | |
| 155 | // Copy to storage using streams |
| 156 | $temp_dir = $this->temp->get_dir(); |
| 157 | |
| 158 | $fp = fopen($temp_dir . '/' . $file, 'rb'); |
| 159 | |
| 160 | if ($fp === false) |
| 161 | { |
| 162 | throw new \phpbb\exception\runtime_exception('CANNOT_OPEN_FILE'); |
| 163 | } |
| 164 | |
| 165 | $storage->write($file, $fp); |
| 166 | |
| 167 | // Remove file from tmp |
| 168 | @unlink($temp_dir . '/' . $file); |
| 169 | |
| 170 | // Save to database |
| 171 | $sql = "INSERT INTO " . $table_prefix . "backups (filename) |
| 172 | VALUES ('$file');"; |
| 173 | $db->sql_query($sql); |
| 174 | } |
| 175 | catch (\phpbb\exception\runtime_exception $e) |
| 176 | { |
| 177 | trigger_error($e->getMessage(), E_USER_ERROR); |
| 178 | } |
| 179 | |
| 180 | $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP'); |
| 181 | |
| 182 | trigger_error($user->lang['BACKUP_SUCCESS'] . adm_back_link($this->u_action)); |
| 183 | break; |
| 184 | |
| 185 | default: |
| 186 | $tables = $this->db_tools->sql_list_tables(); |
| 187 | asort($tables); |
| 188 | foreach ($tables as $table_name) |
| 189 | { |
| 190 | if (strlen($table_prefix) === 0 || stripos($table_name, $table_prefix) === 0) |
| 191 | { |
| 192 | $template->assign_block_vars('tables', array( |
| 193 | 'TABLE' => $table_name |
| 194 | )); |
| 195 | } |
| 196 | } |
| 197 | unset($tables); |
| 198 | |
| 199 | $template->assign_vars(array( |
| 200 | 'U_ACTION' => $this->u_action . '&action=download' |
| 201 | )); |
| 202 | |
| 203 | $available_methods = array('gzip' => 'zlib', 'bzip2' => 'bz2'); |
| 204 | |
| 205 | foreach ($available_methods as $type => $module) |
| 206 | { |
| 207 | if (!@extension_loaded($module)) |
| 208 | { |
| 209 | continue; |
| 210 | } |
| 211 | |
| 212 | $template->assign_block_vars('methods', array( |
| 213 | 'TYPE' => $type |
| 214 | )); |
| 215 | } |
| 216 | |
| 217 | $template->assign_block_vars('methods', array( |
| 218 | 'TYPE' => 'text' |
| 219 | )); |
| 220 | break; |
| 221 | } |
| 222 | break; |
| 223 | |
| 224 | case 'restore': |
| 225 | |
| 226 | $this->page_title = 'ACP_RESTORE'; |
| 227 | |
| 228 | switch ($action) |
| 229 | { |
| 230 | case 'submit': |
| 231 | $delete = $request->variable('delete', ''); |
| 232 | $file = $request->variable('file', ''); |
| 233 | |
| 234 | $backup_info = $this->get_backup_file($db, $file); |
| 235 | |
| 236 | if (empty($backup_info)) |
| 237 | { |
| 238 | trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 239 | } |
| 240 | |
| 241 | if ($delete) |
| 242 | { |
| 243 | if (confirm_box(true)) |
| 244 | { |
| 245 | try |
| 246 | { |
| 247 | // Delete from storage |
| 248 | $storage->delete($backup_info['file_name']); |
| 249 | |
| 250 | // Add log entry |
| 251 | $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE'); |
| 252 | |
| 253 | // Remove from database |
| 254 | $sql = "DELETE FROM " . $table_prefix . "backups |
| 255 | WHERE filename = '" . $db->sql_escape($backup_info['file_name']) . "';"; |
| 256 | $db->sql_query($sql); |
| 257 | } |
| 258 | catch (\Exception $e) |
| 259 | { |
| 260 | trigger_error($user->lang['BACKUP_DELETE_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 261 | } |
| 262 | |
| 263 | trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action)); |
| 264 | } |
| 265 | else |
| 266 | { |
| 267 | confirm_box(false, $user->lang['DELETE_SELECTED_BACKUP'], build_hidden_fields(array('delete' => $delete, 'file' => $file))); |
| 268 | } |
| 269 | } |
| 270 | else if (confirm_box(true)) |
| 271 | { |
| 272 | // Copy file to temp folder to decompress it |
| 273 | $temp_file_name = $this->temp->get_dir() . '/' . $backup_info['file_name']; |
| 274 | |
| 275 | try |
| 276 | { |
| 277 | $stream = $storage->read($backup_info['file_name']); |
| 278 | $fp = fopen($temp_file_name, 'w+b'); |
| 279 | |
| 280 | stream_copy_to_stream($stream, $fp); |
| 281 | |
| 282 | fclose($fp); |
| 283 | fclose($stream); |
| 284 | } |
| 285 | catch (\phpbb\storage\exception\storage_exception $e) |
| 286 | { |
| 287 | trigger_error($user->lang['RESTORE_DOWNLOAD_FAIL'] . adm_back_link($this->u_action)); |
| 288 | } |
| 289 | |
| 290 | switch ($backup_info['extension']) |
| 291 | { |
| 292 | case 'sql': |
| 293 | $fp = fopen($temp_file_name, 'rb'); |
| 294 | $read = 'fread'; |
| 295 | $seek = 'fseek'; |
| 296 | $eof = 'feof'; |
| 297 | $close = 'fclose'; |
| 298 | $fgetd = 'fgetd'; |
| 299 | break; |
| 300 | |
| 301 | case 'sql.bz2': |
| 302 | $fp = bzopen($temp_file_name, 'r'); |
| 303 | $read = 'bzread'; |
| 304 | $seek = ''; |
| 305 | $eof = 'feof'; |
| 306 | $close = 'bzclose'; |
| 307 | $fgetd = 'fgetd_seekless'; |
| 308 | break; |
| 309 | |
| 310 | case 'sql.gz': |
| 311 | $fp = gzopen($temp_file_name, 'rb'); |
| 312 | $read = 'gzread'; |
| 313 | $seek = 'gzseek'; |
| 314 | $eof = 'gzeof'; |
| 315 | $close = 'gzclose'; |
| 316 | $fgetd = 'fgetd'; |
| 317 | break; |
| 318 | |
| 319 | default: |
| 320 | @unlink($temp_file_name); |
| 321 | trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 322 | return; |
| 323 | } |
| 324 | |
| 325 | switch ($db->get_sql_layer()) |
| 326 | { |
| 327 | case 'mysqli': |
| 328 | case 'sqlite3': |
| 329 | while (($sql = $fgetd($fp, ";\n", $read, $seek, $eof)) !== false) |
| 330 | { |
| 331 | $db->sql_query($sql); |
| 332 | } |
| 333 | break; |
| 334 | |
| 335 | case 'postgres': |
| 336 | $delim = ";\n"; |
| 337 | while (($sql = $fgetd($fp, $delim, $read, $seek, $eof)) !== false) |
| 338 | { |
| 339 | $query = trim($sql); |
| 340 | |
| 341 | if (substr($query, 0, 13) == 'CREATE DOMAIN') |
| 342 | { |
| 343 | list(, , $domain) = explode(' ', $query); |
| 344 | $sql = "SELECT domain_name |
| 345 | FROM information_schema.domains |
| 346 | WHERE domain_name = '$domain';"; |
| 347 | $result = $db->sql_query($sql); |
| 348 | if (!$db->sql_fetchrow($result)) |
| 349 | { |
| 350 | $db->sql_query($query); |
| 351 | } |
| 352 | $db->sql_freeresult($result); |
| 353 | } |
| 354 | else |
| 355 | { |
| 356 | $db->sql_query($query); |
| 357 | } |
| 358 | |
| 359 | if (substr($query, 0, 4) == 'COPY') |
| 360 | { |
| 361 | while (($sub = $fgetd($fp, "\n", $read, $seek, $eof)) !== '\.') |
| 362 | { |
| 363 | if ($sub === false) |
| 364 | { |
| 365 | trigger_error($user->lang['RESTORE_FAILURE'] . adm_back_link($this->u_action), E_USER_WARNING); |
| 366 | } |
| 367 | pg_put_line($db->get_db_connect_id(), $sub . "\n"); |
| 368 | } |
| 369 | pg_put_line($db->get_db_connect_id(), "\\.\n"); |
| 370 | pg_end_copy($db->get_db_connect_id()); |
| 371 | } |
| 372 | } |
| 373 | break; |
| 374 | |
| 375 | case 'oracle': |
| 376 | while (($sql = $fgetd($fp, "/\n", $read, $seek, $eof)) !== false) |
| 377 | { |
| 378 | $db->sql_query($sql); |
| 379 | } |
| 380 | break; |
| 381 | |
| 382 | case 'mssql_odbc': |
| 383 | case 'mssqlnative': |
| 384 | while (($sql = $fgetd($fp, "GO\n", $read, $seek, $eof)) !== false) |
| 385 | { |
| 386 | $db->sql_query($sql); |
| 387 | } |
| 388 | break; |
| 389 | } |
| 390 | |
| 391 | $close($fp); |
| 392 | |
| 393 | @unlink($temp_file_name); |
| 394 | |
| 395 | // Purge the cache due to updated data |
| 396 | $cache->purge(); |
| 397 | |
| 398 | $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_RESTORE'); |
| 399 | trigger_error($user->lang['RESTORE_SUCCESS'] . adm_back_link($this->u_action)); |
| 400 | break; |
| 401 | } |
| 402 | else |
| 403 | { |
| 404 | confirm_box(false, $user->lang['RESTORE_SELECTED_BACKUP'], build_hidden_fields(array('file' => $file))); |
| 405 | } |
| 406 | |
| 407 | default: |
| 408 | $backup_files = $this->get_file_list($db); |
| 409 | |
| 410 | if (!empty($backup_files)) |
| 411 | { |
| 412 | krsort($backup_files); |
| 413 | |
| 414 | foreach ($backup_files as $name => $file) |
| 415 | { |
| 416 | $template->assign_block_vars('files', array( |
| 417 | 'FILE' => sha1($file), |
| 418 | 'NAME' => $user->format_date($name, 'd-m-Y H:i', true), |
| 419 | 'SUPPORTED' => true, |
| 420 | )); |
| 421 | } |
| 422 | } |
| 423 | |
| 424 | $template->assign_vars(array( |
| 425 | 'U_ACTION' => $this->u_action . '&action=submit' |
| 426 | )); |
| 427 | break; |
| 428 | } |
| 429 | break; |
| 430 | } |
| 431 | } |
| 432 | |
| 433 | /** |
| 434 | * Get backup file from file hash |
| 435 | * |
| 436 | * @param \phpbb\db\driver\driver_interface $db Database driver |
| 437 | * @param string $file_hash Hash of selected file |
| 438 | * |
| 439 | * @return array Backup file data or empty array if unable to find file |
| 440 | */ |
| 441 | protected function get_backup_file($db, $file_hash) |
| 442 | { |
| 443 | $backup_data = []; |
| 444 | |
| 445 | $file_list = $this->get_file_list($db); |
| 446 | $supported_extensions = $this->get_supported_extensions(); |
| 447 | |
| 448 | foreach ($file_list as $file) |
| 449 | { |
| 450 | preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches); |
| 451 | if (sha1($file) === $file_hash && in_array($matches[2], $supported_extensions)) |
| 452 | { |
| 453 | $backup_data = [ |
| 454 | 'file_name' => $file, |
| 455 | 'extension' => $matches[2], |
| 456 | ]; |
| 457 | break; |
| 458 | } |
| 459 | } |
| 460 | |
| 461 | return $backup_data; |
| 462 | } |
| 463 | |
| 464 | /** |
| 465 | * Get backup file list for directory |
| 466 | * |
| 467 | * @param \phpbb\db\driver\driver_interface $db Database driver |
| 468 | * |
| 469 | * @return array List of backup files in specified directory |
| 470 | */ |
| 471 | protected function get_file_list($db) |
| 472 | { |
| 473 | $supported_extensions = $this->get_supported_extensions(); |
| 474 | |
| 475 | $backup_files = []; |
| 476 | |
| 477 | $sql = 'SELECT filename |
| 478 | FROM ' . BACKUPS_TABLE; |
| 479 | $result = $db->sql_query($sql); |
| 480 | |
| 481 | while ($row = $db->sql_fetchrow($result)) |
| 482 | { |
| 483 | if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $row['filename'], $matches)) |
| 484 | { |
| 485 | if (in_array($matches[2], $supported_extensions)) |
| 486 | { |
| 487 | $backup_files[(int) $matches[1]] = $row['filename']; |
| 488 | } |
| 489 | } |
| 490 | } |
| 491 | $db->sql_freeresult($result); |
| 492 | |
| 493 | return $backup_files; |
| 494 | } |
| 495 | |
| 496 | /** |
| 497 | * Get supported extensions for backup |
| 498 | * |
| 499 | * @return array List of supported extensions |
| 500 | */ |
| 501 | protected function get_supported_extensions() |
| 502 | { |
| 503 | $extensions = ['sql']; |
| 504 | $available_methods = ['sql.gz' => 'zlib', 'sql.bz2' => 'bz2']; |
| 505 | |
| 506 | foreach ($available_methods as $type => $module) |
| 507 | { |
| 508 | if (!@extension_loaded($module)) |
| 509 | { |
| 510 | continue; |
| 511 | } |
| 512 | $extensions[] = $type; |
| 513 | } |
| 514 | |
| 515 | return $extensions; |
| 516 | } |
| 517 | } |
| 518 | |
| 519 | // get how much space we allow for a chunk of data, very similar to phpMyAdmin's way of doing things ;-) (hey, we only do this for MySQL anyway :P) |
| 520 | function get_usable_memory() |
| 521 | { |
| 522 | $val = trim(@ini_get('memory_limit')); |
| 523 | |
| 524 | if (preg_match('/(\\d+)([mkg]?)/i', $val, $regs)) |
| 525 | { |
| 526 | $memory_limit = (int) $regs[1]; |
| 527 | switch ($regs[2]) |
| 528 | { |
| 529 | |
| 530 | case 'k': |
| 531 | case 'K': |
| 532 | $memory_limit *= 1024; |
| 533 | break; |
| 534 | |
| 535 | case 'm': |
| 536 | case 'M': |
| 537 | $memory_limit *= 1048576; |
| 538 | break; |
| 539 | |
| 540 | case 'g': |
| 541 | case 'G': |
| 542 | $memory_limit *= 1073741824; |
| 543 | break; |
| 544 | } |
| 545 | |
| 546 | // how much memory PHP requires at the start of export (it is really a little less) |
| 547 | if ($memory_limit > 6100000) |
| 548 | { |
| 549 | $memory_limit -= 6100000; |
| 550 | } |
| 551 | |
| 552 | // allow us to consume half of the total memory available |
| 553 | $memory_limit /= 2; |
| 554 | } |
| 555 | else |
| 556 | { |
| 557 | // set the buffer to 1M if we have no clue how much memory PHP will give us :P |
| 558 | $memory_limit = 1048576; |
| 559 | } |
| 560 | |
| 561 | return $memory_limit; |
| 562 | } |
| 563 | |
| 564 | function sanitize_data_mssql($text) |
| 565 | { |
| 566 | $data = preg_split('/[\n\t\r\b\f]/', $text); |
| 567 | preg_match_all('/[\n\t\r\b\f]/', $text, $matches); |
| 568 | |
| 569 | $val = array(); |
| 570 | |
| 571 | foreach ($data as $value) |
| 572 | { |
| 573 | if (strlen($value)) |
| 574 | { |
| 575 | $val[] = "'" . $value . "'"; |
| 576 | } |
| 577 | if (count($matches[0])) |
| 578 | { |
| 579 | $val[] = 'char(' . ord(array_shift($matches[0])) . ')'; |
| 580 | } |
| 581 | } |
| 582 | |
| 583 | return implode('+', $val); |
| 584 | } |
| 585 | |
| 586 | function sanitize_data_oracle($text) |
| 587 | { |
| 588 | // $data = preg_split('/[\0\n\t\r\b\f\'"\/\\\]/', $text); |
| 589 | // preg_match_all('/[\0\n\t\r\b\f\'"\/\\\]/', $text, $matches); |
| 590 | $data = preg_split('/[\0\b\f\'\/]/', $text); |
| 591 | preg_match_all('/[\0\r\b\f\'\/]/', $text, $matches); |
| 592 | |
| 593 | $val = array(); |
| 594 | |
| 595 | foreach ($data as $value) |
| 596 | { |
| 597 | if (strlen($value)) |
| 598 | { |
| 599 | $val[] = "'" . $value . "'"; |
| 600 | } |
| 601 | if (count($matches[0])) |
| 602 | { |
| 603 | $val[] = 'chr(' . ord(array_shift($matches[0])) . ')'; |
| 604 | } |
| 605 | } |
| 606 | |
| 607 | return implode('||', $val); |
| 608 | } |
| 609 | |
| 610 | function sanitize_data_generic($text) |
| 611 | { |
| 612 | $data = preg_split('/[\n\t\r\b\f]/', $text); |
| 613 | preg_match_all('/[\n\t\r\b\f]/', $text, $matches); |
| 614 | |
| 615 | $val = array(); |
| 616 | |
| 617 | foreach ($data as $value) |
| 618 | { |
| 619 | if (strlen($value)) |
| 620 | { |
| 621 | $val[] = "'" . $value . "'"; |
| 622 | } |
| 623 | if (count($matches[0])) |
| 624 | { |
| 625 | $val[] = "'" . array_shift($matches[0]) . "'"; |
| 626 | } |
| 627 | } |
| 628 | |
| 629 | return implode('||', $val); |
| 630 | } |
| 631 | |
| 632 | // modified from PHP.net |
| 633 | function fgetd(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) |
| 634 | { |
| 635 | $record = ''; |
| 636 | $delim_len = strlen($delim); |
| 637 | |
| 638 | while (!$eof($fp)) |
| 639 | { |
| 640 | $pos = strpos($record, $delim); |
| 641 | if ($pos === false) |
| 642 | { |
| 643 | $record .= $read($fp, $buffer); |
| 644 | if ($eof($fp) && ($pos = strpos($record, $delim)) !== false) |
| 645 | { |
| 646 | $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); |
| 647 | return substr($record, 0, $pos); |
| 648 | } |
| 649 | } |
| 650 | else |
| 651 | { |
| 652 | $seek($fp, $pos + $delim_len - strlen($record), SEEK_CUR); |
| 653 | return substr($record, 0, $pos); |
| 654 | } |
| 655 | } |
| 656 | |
| 657 | return false; |
| 658 | } |
| 659 | |
| 660 | function fgetd_seekless(&$fp, $delim, $read, $seek, $eof, $buffer = 8192) |
| 661 | { |
| 662 | static $array = array(); |
| 663 | static $record = ''; |
| 664 | |
| 665 | if (!count($array)) |
| 666 | { |
| 667 | while (!$eof($fp)) |
| 668 | { |
| 669 | if (strpos($record, $delim) !== false) |
| 670 | { |
| 671 | $array = explode($delim, $record); |
| 672 | $record = array_pop($array); |
| 673 | break; |
| 674 | } |
| 675 | else |
| 676 | { |
| 677 | $record .= $read($fp, $buffer); |
| 678 | } |
| 679 | } |
| 680 | if ($eof($fp) && strpos($record, $delim) !== false) |
| 681 | { |
| 682 | $array = explode($delim, $record); |
| 683 | $record = array_pop($array); |
| 684 | } |
| 685 | } |
| 686 | |
| 687 | if (count($array)) |
| 688 | { |
| 689 | return array_shift($array); |
| 690 | } |
| 691 | |
| 692 | return false; |
| 693 | } |