Skip to content

Commit

Permalink
Merge pull request #56 from nguyenanhung/v3.2.0-develop
Browse files Browse the repository at this point in the history
V3.2.0 develop
  • Loading branch information
nguyenanhung authored Sep 9, 2024
2 parents 9c18c60 + 85aa856 commit 0a9da9e
Show file tree
Hide file tree
Showing 16 changed files with 288 additions and 178 deletions.
26 changes: 25 additions & 1 deletion system/core/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,30 @@ function is_linux()

// ------------------------------------------------------------------------

if ( ! function_exists('mt_random_int'))
{
function mt_random_int()
{
if (is_php('7.0') && (function_exists('random_int') && defined(PHP_INT_MIN) && defined('PHP_INT_MAX')))
{
try {
return random_int(PHP_INT_MIN, PHP_INT_MAX);
}
catch (Exception $e)
{
log_message('error', 'Error Code: '.$e->getCode().' - File: '.$e->getFile().' - Line: '.$e->getLine().' - Message: '.$e->getMessage());
return mt_rand();
}
}
else
{
return mt_rand();
}
}
}

// ------------------------------------------------------------------------

if ( ! function_exists('is_really_writable'))
{
/**
Expand All @@ -128,7 +152,7 @@ function is_really_writable($file)
*/
if (is_dir($file))
{
$file = rtrim($file, '/').'/'.md5(mt_rand());
$file = rtrim($file, '/').'/'.md5(mt_random_int());
if (($fp = @fopen($file, 'ab')) === FALSE)
{
return FALSE;
Expand Down
4 changes: 2 additions & 2 deletions system/core/Security.php
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ public function xss_hash()
if ($this->_xss_hash === null) {
$rand = $this->get_random_bytes(16);
$this->_xss_hash = ($rand === false)
? md5(uniqid(mt_rand(), true))
? md5(uniqid(mt_random_int(), true))
: bin2hex($rand);
}

Expand Down Expand Up @@ -1237,7 +1237,7 @@ protected function _csrf_set_hash()

$rand = $this->get_random_bytes(16);
$this->_csrf_hash = ($rand === false)
? md5(uniqid(mt_rand(), true))
? md5(uniqid(mt_random_int(), true))
: bin2hex($rand);
}

Expand Down
38 changes: 24 additions & 14 deletions system/database/DB_driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,20 @@ abstract class CI_DB_driver {
*/
protected $_like_escape_chr = '!';

/**
* RegExp used to escape identifiers
*
* @var array
*/
protected $_preg_escape_char = array();

/**
* RegExp used to get operators
*
* @var string[]
*/
protected $_preg_operators = array();

/**
* ORDER BY random keyword
*
Expand Down Expand Up @@ -1410,18 +1424,16 @@ public function escape_identifiers($item)
return $item;
}
// Avoid breaking functions and literal values inside queries
elseif (ctype_digit($item) OR $item[0] === "'" OR ($this->_escape_char !== '"' && $item[0] === '"') OR strpos($item, '(') !== FALSE)
elseif (ctype_digit((string) $item) OR $item[0] === "'" OR ($this->_escape_char !== '"' && $item[0] === '"') OR strpos($item, '(') !== FALSE)
{
return $item;
}

static $preg_ec = array();

if (empty($preg_ec))
if (empty($this->_preg_escape_char))
{
if (is_array($this->_escape_char))
{
$preg_ec = array(
$this->_preg_escape_char = array(
preg_quote($this->_escape_char[0], '/'),
preg_quote($this->_escape_char[1], '/'),
$this->_escape_char[0],
Expand All @@ -1430,20 +1442,20 @@ public function escape_identifiers($item)
}
else
{
$preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char, '/');
$preg_ec[2] = $preg_ec[3] = $this->_escape_char;
$this->_preg_escape_char[0] = $this->_preg_escape_char[1] = preg_quote($this->_escape_char, '/');
$this->_preg_escape_char[2] = $this->_preg_escape_char[3] = $this->_escape_char;
}
}

foreach ($this->_reserved_identifiers as $id)
{
if (strpos($item, '.'.$id) !== FALSE)
{
return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\./i', $preg_ec[2].'$1'.$preg_ec[3].'.', $item);
return preg_replace('/'.$this->_preg_escape_char[0].'?([^'.$this->_preg_escape_char[1].'\.]+)'.$this->_preg_escape_char[1].'?\./i', $this->_preg_escape_char[2].'$1'.$this->_preg_escape_char[3].'.', $item);
}
}

return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?(\.)?/i', $preg_ec[2].'$1'.$preg_ec[3].'$2', $item);
return preg_replace('/'.$this->_preg_escape_char[0].'?([^'.$this->_preg_escape_char[1].'\.]+)'.$this->_preg_escape_char[1].'?(\.)?/i', $this->_preg_escape_char[2].'$1'.$this->_preg_escape_char[3].'$2', $item);
}

// --------------------------------------------------------------------
Expand Down Expand Up @@ -1562,14 +1574,12 @@ protected function _has_operator($str)
*/
protected function _get_operator($str)
{
static $_operators;

if (empty($_operators))
if (empty($this->_preg_operators))
{
$_les = ($this->_like_escape_str !== '')
? '\s+'.preg_quote(trim(sprintf($this->_like_escape_str, $this->_like_escape_chr)), '/')
: '';
$_operators = array(
$this->_preg_operators = array(
'\s*(?:<|>|!)?=\s*', // =, <=, >=, !=
'\s*<>?\s*', // <, <>
'\s*>\s*', // >
Expand All @@ -1587,7 +1597,7 @@ protected function _get_operator($str)

}

return preg_match('/'.implode('|', $_operators).'/i', $str, $match)
return preg_match('/'.implode('|', $this->_preg_operators).'/i', $str, $match)
? $match[0] : FALSE;
}

Expand Down
21 changes: 13 additions & 8 deletions system/database/DB_query_builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
*/
protected $qb_cache_no_escape = array();

/**
* Strings that determine if a string represents a literal value or a field name
*
* @var string[]
*/
protected $is_literal_str = array();

// --------------------------------------------------------------------

/**
Expand Down Expand Up @@ -1525,7 +1532,7 @@ public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size =
{
if (empty($set))
{
return ($this->db_debug) ? $this->display_error('insert_batch() called with no data') : FALSE;
return ($this->db_debug) ? $this->display_error('db_data_required', 'insert_batch()') : FALSE;
}

$this->set_insert_batch($set, '', $escape);
Expand Down Expand Up @@ -1942,7 +1949,7 @@ public function update_batch($table, $set = NULL, $index = NULL, $batch_size = 1
{
if (empty($set))
{
return ($this->db_debug) ? $this->display_error('update_batch() called with no data') : FALSE;
return ($this->db_debug) ? $this->display_error('db_data_required', 'update_batch()') : FALSE;
}

$this->set_update_batch($set, $index);
Expand Down Expand Up @@ -2739,20 +2746,18 @@ protected function _is_literal($str)
{
$str = trim($str);

if (empty($str) OR ctype_digit($str) OR (string) (float) $str === $str OR in_array(strtoupper($str), array('TRUE', 'FALSE'), TRUE))
if (empty($str) OR ctype_digit((string) $str) OR (string) (float) $str === $str OR in_array(strtoupper($str), array('TRUE', 'FALSE'), TRUE))
{
return TRUE;
}

static $_str;

if (empty($_str))
if (empty($this->is_literal_str))
{
$_str = ($this->_escape_char !== '"')
$this->is_literal_str = ($this->_escape_char !== '"')
? array('"', "'") : array("'");
}

return in_array($str[0], $_str, TRUE);
return in_array($str[0], $this->is_literal_str, TRUE);
}

// --------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions system/database/drivers/oci8/oci8_driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public function __construct($params)
return;
}
elseif ($this->hostname !== '' && strpos($this->hostname, '/') === FALSE && strpos($this->hostname, ':') === FALSE
&& (( ! empty($this->port) && ctype_digit($this->port)) OR $this->database !== ''))
&& (( ! empty($this->port) && ctype_digit((string) $this->port)) OR $this->database !== ''))
{
/* If the hostname field isn't empty, doesn't contain
* ':' and/or '/' and if port and/or database aren't
Expand All @@ -189,7 +189,7 @@ public function __construct($params)
* that the database field is a service name.
*/
$this->dsn = $this->hostname
.(( ! empty($this->port) && ctype_digit($this->port)) ? ':'.$this->port : '')
.(( ! empty($this->port) && ctype_digit((string) $this->port)) ? ':'.$this->port : '')
.($this->database !== '' ? '/'.ltrim($this->database, '/') : '');

if (preg_match($valid_dsns['ec'], $this->dsn))
Expand Down
2 changes: 1 addition & 1 deletion system/database/drivers/postgre/postgre_driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ protected function _build_dsn()

$this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' ';

if ( ! empty($this->port) && ctype_digit($this->port))
if ( ! empty($this->port) && ctype_digit((string) $this->port))
{
$this->dsn .= 'port='.$this->port.' ';
}
Expand Down
18 changes: 9 additions & 9 deletions system/helpers/string_helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ function random_string($type = 'alnum', $length = 16)
{
switch ($type) {
case 'basic':
return mt_rand();
return mt_random_int();
break;

default:
Expand Down Expand Up @@ -247,33 +247,33 @@ function random_string($type = 'alnum', $length = 16)

$str = '';
for ($i = 0; $i < $length; $i++) {
$str .= substr($pool, mt_rand(0, strlen($pool) - 1), 1);
$str .= substr($pool, mt_random_int(0, strlen($pool) - 1), 1);
}

return $str;
break;

case 'md5':
case 'unique':
return md5(uniqid(mt_rand(), true));
return md5(uniqid(mt_random_int(), true));
break;
case 'base64':
return base64_encode(md5(uniqid(mt_rand(), true)));
return base64_encode(md5(uniqid(mt_random_int(), true)));
break;
case 'sha1' :
return sha1(uniqid(mt_rand(), true));
return sha1(uniqid(mt_random_int(), true));
break;
case 'sha256' :
return hash('sha256', uniqid(mt_rand(), true));
return hash('sha256', uniqid(mt_random_int(), true));
break;
case 'sha384' :
return hash('sha384', uniqid(mt_rand(), true));
return hash('sha384', uniqid(mt_random_int(), true));
break;
case 'sha512' :
return hash('sha512', uniqid(mt_rand(), true));
return hash('sha512', uniqid(mt_random_int(), true));
break;
case 'whirlpool' :
return hash('whirlpool', uniqid(mt_rand(), true));
return hash('whirlpool', uniqid(mt_random_int(), true));
break;
case 'uuid':
$pool = array('8', '9', 'a', 'b');
Expand Down
1 change: 1 addition & 0 deletions system/language/english/db_lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@
$lang['db_column_definition_required'] = 'A column definition is required for that operation.';
$lang['db_unable_to_set_charset'] = 'Unable to set client connection character set: %s';
$lang['db_error_heading'] = 'A Database Error Occurred';
$lang['db_data_required'] = '%s called with no data';
94 changes: 94 additions & 0 deletions system/libraries/CI_Luhn.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

defined('BASEPATH') or exit('No direct script access allowed');

/**
* Luhn algorithm.
*
* The Luhn algorithm or Luhn formula, also known as the "modulus 10" or
* "mod 10" algorithm, is a simple checksum formula used to validate a
* variety of identification numbers, such as credit card numbers,
* IMEI numbers, National Provider Identifier numbers in the US, and
* Canadian Social Insurance Numbers. It was created by IBM scientist
* Hans Peter Luhn and described in U.S. Patent No. 2,950,048, filed
* on January 6, 1954, and granted on August 23, 1960.
*
* Originally: https://github.com/selective-php/luhn/blob/master/src/Luhn.php
*/
#[AllowDynamicProperties]
class CI_Luhn
{
/**
* Returns the luhn check digit.
*
* @param string $numbers Numbers as string
*
* @return int Checksum digit
*/
public function create(string $numbers): int
{
$this->validateNumericString($numbers);

// Add a zero check digit
$numbers .= '0';
$sum = 0;
// Find the last character
$i = strlen($numbers);
$odd_length = $i % 2;
// Iterate all digits backwards
while ($i-- > 0) {
// Add the current digit
$sum += $numbers[$i];
// If the digit is even, add it again. Adjust for digits 10+ by subtracting 9.
if ($odd_length === ($i % 2) && $numbers[$i] > 4) {
$sum += ((int)$numbers[$i] - 9);
}
if ($odd_length === ($i % 2) && $numbers[$i] <= 4) {
$sum += $numbers[$i];
}
}

return (10 - ($sum % 10)) % 10;
}

/**
* Check luhn number.
*
* @param string $number The number to validate
*
* @return bool Status
*/
public function validate(string $number): bool
{
$this->validateNumericString($number);

$sum = 0;
$numDigits = strlen($number) - 1;
$parity = $numDigits % 2;

for ($i = $numDigits; $i >= 0; $i--) {
$digit = (int)substr($number, $i, 1);
if (!$parity == ($i % 2)) {
$digit <<= 1;
}
$digit = ($digit > 9) ? ($digit - 9) : $digit;
$sum += $digit;
}

return 0 == ($sum % 10);
}

/**
* Validate numeric string.
*
* @param string $number The number to validate
*
* @return void
*/
private function validateNumericString(string $number): void
{
if (!preg_match('/^\d+$/', $number)) {
throw new InvalidArgumentException(sprintf('An invalid numeric value was given: %s', $number));
}
}
}
Loading

0 comments on commit 0a9da9e

Please sign in to comment.