Page MenuHomeDevCentral

No OneTemporary

diff --git a/core.php b/core.php
index e0c6b83..38406a3 100644
--- a/core.php
+++ b/core.php
@@ -1,175 +1,206 @@
<?php
namespace Keruald;
/**
* Keruald, core libraries for Pluton and Xen engines.
*
* Global functions
*/
///
/// Strings
///
/**
* Pads a multibytes string to a certain length with another string
*
* @param string $str the input string
* @param int $pad_length the target string size
* @param string $pad_string the padding characters (optional, default is space)
* @param int $pad_type STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH (optional, default is STR_PAD_RIGHT)
* @param string the character encoding (optional)
*
* @return string the padded string
*
*/
function mb_str_pad($input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT, $encoding = null) {
// Inspired by Ronald Ulysses Swanson method
// http://stackoverflow.com/a/27194169/1930997
// who followed the str_pad PHP implementation.
if ($encoding === null) {
$encoding = mb_internal_encoding();
}
$padBefore = $pad_type === STR_PAD_BOTH || $pad_type === STR_PAD_LEFT;
$padAfter = $pad_type === STR_PAD_BOTH || $pad_type === STR_PAD_RIGHT;
$pad_length -= mb_strlen($input, $encoding);
if ($padBefore && $padAfter) {
$targetLength = $pad_length / 2;
} else {
$targetLength = $pad_length;
}
$strToRepeatLength = mb_strlen($pad_string, $encoding);
$repeatTimes = ceil($targetLength / $strToRepeatLength);
$repeatedString = str_repeat($pad_string, max(0, $repeatTimes)); // safe if used with valid Unicode sequences (any charset)
$paddedString = '';
if ($padBefore) {
$paddedString = mb_substr($repeatedString, 0, floor($targetLength), $encoding);
}
$paddedString .= $input;
if ($padAfter) {
$paddedString .= mb_substr($repeatedString, 0, ceil($targetLength), $encoding);
}
return $paddedString;
}
+/**
+ * Determines whether the specified is a valid IP address
+ *
+ * @param $string the string to validate as an IP
+ * @return bool true if the specified string is a valid IP address; otherwise, false
+ */
+function is_ip ($string) {
+ return is_ipv4($string) || is_ipv6($string);
+}
+
+/**
+ * Determines whether the specified is a valid IPv4 address
+ *
+ * @param $string the string to validate as an IP
+ * @return bool true if the specified string is a valid IPv4 address; otherwise, false
+ */
+function is_ipv4 ($string) {
+ return filter_var($string, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false;
+}
+
+/**
+ * Determines whether the specified is a valid IPv6 address
+ *
+ * @param $string the string to validate as an IP
+ * @return bool true if the specified string is a valid IPv6 address; otherwise, false
+ */
+function is_ipv6 ($string) {
+ return filter_var($string, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false;
+}
+
+
///
/// Identifiers
///
/**
* Generates a RFC 4211 compliant v4 UUID (random-based)
*
* @return string The UUID
*/
function uuid () {
//Code by Andrew Moore
//See http://php.net/manual/en/function.uniqid.php#94959
// https://www.ietf.org/rfc/rfc4122.txt
return sprintf(
'%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
// 32 bits for "time_low"
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
// 16 bits for "time_mid"
mt_rand(0, 0xffff),
// 16 bits for "time_hi_and_version",
// four most significant bits holds version number 4
mt_rand(0, 0x0fff) | 0x4000,
// 16 bits, 8 bits for "clk_seq_hi_res",
// 8 bits for "clk_seq_low",
// two most significant bits holds zero and one for variant DCE1.1
mt_rand(0, 0x3fff) | 0x8000,
// 48 bits for "node"
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
///
/// Error and debug
///
/**
* Prints human-readable information about a variable, wrapped in a <pre> block
*
* @param mixed $variable the variable to dump
*/
function dprint_r ($variable) {
echo '<pre>';
print_r($variable);
echo '</pre>';
}
/**
* Prints human-readable information about a variable, wrapped in a <pre> block
* then dies
*
* @param mixed $variable the variable to dump
*/
function dieprint_r ($variable) {
dprint_r($variable);
die;
};
///
/// Client information
///
/**
* Returns the full header or the IP part of it
*
* @param string $value The header value
* @return string the IP part
*/
function extract_client_ip_from_header ($value) {
if (strpos($value, ',') !== false) {
//Header contains 'clientIP, proxyIP, anotherProxyIP'
//The first value is so the one to return.
//See draft-ietf-appsawg-http-forwarded-10.
$ips = explode(',', $value, 2);
return trim($ips[0]);
}
return $value;
}
/**
* Gets remote IP address.
*
* This is intended as a drop-in replacement for $_SERVER['REMOTE_ADDR'],
* which takes in consideration proxy values, blindly trusted.
*/
function get_remote_addr () {
$candidates = [
//Standard header provided by draft-ietf-appsawg-http-forwarded-10
'HTTP_X_FORWARDED_FOR',
//Legacy headers
'HTTP_CLIENT_IP',
'HTTP_FORWARDED',
'HTTP_FORWARDED_FOR',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_X_FORWARDED',
//Default header if no proxy information could be detected
'REMOTE_ADDR',
];
foreach ($candidates as $candidate) {
if (array_key_exists($candidate, $_SERVER)) {
return extract_client_ip_from_header($_SERVER[$candidate]);
}
}
return '';
}
diff --git a/tests/CoreTest.php b/tests/CoreTest.php
index 47e9fe0..ca1bdcd 100644
--- a/tests/CoreTest.php
+++ b/tests/CoreTest.php
@@ -1,98 +1,138 @@
<?php
namespace Keruald;
class CoreTest extends \PHPUnit_Framework_Testcase {
///
/// Strings
///
function test_mb_str_pad () {
// Tests from http://3v4l.org/UnXTF
// http://web.archive.org/web/20150711100913/http://3v4l.org/UnXTF
$this->assertEquals('àèòàFOOàèòà', mb_str_pad("FOO", 11, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('àèòFOOàèòà', mb_str_pad("FOO", 10, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('àèòBAAZàèòà', mb_str_pad("BAAZ", 11, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('àèòBAAZàèò', mb_str_pad("BAAZ", 10, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 6, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 1, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 0, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", -10, "àèò", STR_PAD_BOTH, "UTF-8"));
$this->assertEquals('àèòàèòàèFOO', mb_str_pad("FOO", 11, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('àèòàèòàFOO', mb_str_pad("FOO", 10, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('àèòàèòàBAAZ', mb_str_pad("BAAZ", 11, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('àèòàèòBAAZ', mb_str_pad("BAAZ", 10, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 6, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 1, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 0, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", -10, "àèò", STR_PAD_LEFT, "UTF-8"));
$this->assertEquals('FOOàèòàèòàè', mb_str_pad("FOO", 11, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('FOOàèòàèòà', mb_str_pad("FOO", 10, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('BAAZàèòàèòà', mb_str_pad("BAAZ", 11, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('BAAZàèòàèò', mb_str_pad("BAAZ", 10, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 6, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 1, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", 0, "àèò", STR_PAD_RIGHT, "UTF-8"));
$this->assertEquals('FOOBAR', mb_str_pad("FOOBAR", -10, "àèò", STR_PAD_RIGHT, "UTF-8"));
}
+ function test_is_ip () {
+ $this->assertTrue(is_ip("0.0.0.0"));
+ $this->assertFalse(is_ip(""));
+ $this->assertFalse(is_ip("1"));
+ $this->assertFalse(is_ip("17.17"));
+ $this->assertTrue(is_ip("17.17.17.17"));
+ $this->assertFalse(is_ip("17.17.17.256"));
+ $this->assertTrue(is_ip("fe80:0000:0000:0000:0204:61ff:fe9d:f156"));
+ }
+
+ function test_is_ipv4 () {
+ $this->assertTrue(is_ipv4("0.0.0.0"));
+ $this->assertFalse(is_ipv4(""));
+ $this->assertFalse(is_ipv4("1"));
+ $this->assertFalse(is_ipv4("17.17"));
+ $this->assertTrue(is_ipv4("17.17.17.17"));
+ $this->assertFalse(is_ipv4("17.17.17.256"));
+ $this->assertFalse(is_ipv4(""));
+ $this->assertFalse(is_ipv4("fe80:0000:0000:0000:0204:61ff:fe9d:f156"));
+ }
+
+ function test_is_ipv6 () {
+ $this->assertFalse(is_ipv6("0.0.0.0"));
+ $this->assertFalse(is_ipv6(""));
+ $this->assertFalse(is_ipv6("1"));
+ $this->assertFalse(is_ipv6("17.17"));
+ $this->assertFalse(is_ipv6("17.17.17.17"));
+ $this->assertTrue(is_ipv6("::1"));
+ $this->assertFalse(is_ipv6("::fg"));
+ $this->assertTrue(is_ipv6("::1"));
+
+ //Advanced IPv6 tests curated by Stephen Ryan
+ //Source: http://forums.dartware.com/viewtopic.php?t=452
+ $this->assertTrue(is_ipv6("fe80:0000:0000:0000:0204:61ff:fe9d:f156"));
+ $this->assertFalse(is_ipv6("02001:0000:1234:0000:0000:C1C0:ABCD:0876"), "extra 0 not allowed");
+ $this->assertFalse(is_ipv6("2001:0000:1234:0000:00001:C1C0:ABCD:0876"), "extra 0 not allowed");
+ $this->assertFalse(is_ipv6("1.2.3.4:1111:2222:3333:4444::5555"));
+ $this->assertTrue(is_ipv6("::ffff:192.0.2.128"), "can't validate IPv4 represented as dotted-quads");
+ }
+
///
/// Identifiers
///
function test_uuid () {
$uuid = uuid();
$this->assertEquals(36, strlen($uuid));
for ($i = 0 ; $i < 36 ; $i++) {
if ($i == 8 | $i == 13 || $i == 18 || $i == 23) {
$this->assertEquals("-", $uuid[$i], "Dash were expected.");
continue;
}
$this->assertRegExp('/[0-9a-f]/', $uuid[$i], "Lowercase hexadecimal digit were expected.");
}
}
///
/// Client information
///
function test_extract_client_ip_from_header () {
$values = [
//Each value should return 10.0.0.3
'10.0.0.3',
'10.0.0.3,10.0.0.4',
'10.0.0.3, 10.0.0.4',
'10.0.0.3, 10.0.0.4, lorem ipsum dolor',
];
foreach ($values as $value) {
$this->assertEquals(
'10.0.0.3',
extract_client_ip_from_header($value)
);
}
$this->assertEmpty(
extract_client_ip_from_header('')
);
}
function test_get_remote_addr () {
$this->assertEmpty(get_remote_addr());
$_SERVER = [
'REMOTE_ADDR' => '10.0.0.2'
];
$this->assertEquals('10.0.0.2', get_remote_addr());
$_SERVER += [
'HTTP_X_FORWARDED_FOR' => '10.0.0.3',
'HTTP_CLIENT_IP' => '10.0.0.4',
];
$this->assertEquals('10.0.0.3', get_remote_addr(), "HTTP_X_FORWARDED_FOR must be prioritized.");
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 02:07 (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2989799
Default Alt Text
(11 KB)

Event Timeline