update ip-lib library from 1.20.0 to 1.21.0

This commit is contained in:
El RIDO
2025-10-09 09:32:17 +02:00
parent 06496a1b0e
commit bcf549ed06
18 changed files with 597 additions and 125 deletions

View File

@@ -5,7 +5,7 @@
* ADDED: Added `shortenviashlink` endpoint with an `shlink` configuration section * ADDED: Added `shortenviashlink` endpoint with an `shlink` configuration section
* ADDED: Password peek (#1254) * ADDED: Password peek (#1254)
* CHANGED: CSP recommendation around bootstrap5 template resolved in Firefox 131 (#1613) * CHANGED: CSP recommendation around bootstrap5 template resolved in Firefox 131 (#1613)
* CHANGED: Upgrading libraries to: bootstrap 5.3.8 & DOMpurify 3.2.7 * CHANGED: Upgrading libraries to: bootstrap 5.3.8, DOMpurify 3.2.7 & ip-lib 1.21.0
* FIXED: Allow pasting a password for decrypting a paste (#1620) * FIXED: Allow pasting a password for decrypting a paste (#1620)
* FIXED: Allow copying the shortened link after using a URL shortener (#1624) * FIXED: Allow copying the shortened link after using a URL shortener (#1624)
* FIXED: URL extraction fails when frame-ancestors is set in CSP (#1644) * FIXED: URL extraction fails when frame-ancestors is set in CSP (#1644)

View File

@@ -26,7 +26,7 @@
"require" : { "require" : {
"php": "^7.4 || ^8.0", "php": "^7.4 || ^8.0",
"jdenticon/jdenticon": "2.0.0", "jdenticon/jdenticon": "2.0.0",
"mlocati/ip-lib": "1.20.0", "mlocati/ip-lib": "1.21.0",
"symfony/polyfill-php80": "1.31.0", "symfony/polyfill-php80": "1.31.0",
"yzalis/identicon": "2.0.0" "yzalis/identicon": "2.0.0"
}, },

156
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "cc778a671eac2ba1ec70bf9398b2e1bf", "content-hash": "f008f704483472b237031d4fa389cb70",
"packages": [ "packages": [
{ {
"name": "jdenticon/jdenticon", "name": "jdenticon/jdenticon",
@@ -57,16 +57,16 @@
}, },
{ {
"name": "mlocati/ip-lib", "name": "mlocati/ip-lib",
"version": "1.20.0", "version": "1.21.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/mlocati/ip-lib.git", "url": "https://github.com/mlocati/ip-lib.git",
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4" "reference": "b5d38cdcbfc1516604d821a1f3f4a1638f327267"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/fd45fc3bf08ed6c7e665e2e70562082ac954afd4", "url": "https://api.github.com/repos/mlocati/ip-lib/zipball/b5d38cdcbfc1516604d821a1f3f4a1638f327267",
"reference": "fd45fc3bf08ed6c7e665e2e70562082ac954afd4", "reference": "b5d38cdcbfc1516604d821a1f3f4a1638f327267",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -112,7 +112,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/mlocati/ip-lib/issues", "issues": "https://github.com/mlocati/ip-lib/issues",
"source": "https://github.com/mlocati/ip-lib/tree/1.20.0" "source": "https://github.com/mlocati/ip-lib/tree/1.21.0"
}, },
"funding": [ "funding": [
{ {
@@ -124,7 +124,7 @@
"type": "other" "type": "other"
} }
], ],
"time": "2025-02-04T17:30:58+00:00" "time": "2025-09-24T13:58:50+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
@@ -337,16 +337,16 @@
}, },
{ {
"name": "myclabs/deep-copy", "name": "myclabs/deep-copy",
"version": "1.13.3", "version": "1.13.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/myclabs/DeepCopy.git", "url": "https://github.com/myclabs/DeepCopy.git",
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36" "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/faed855a7b5f4d4637717c2b3863e277116beb36", "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"reference": "faed855a7b5f4d4637717c2b3863e277116beb36", "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -385,7 +385,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/myclabs/DeepCopy/issues", "issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.3" "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
}, },
"funding": [ "funding": [
{ {
@@ -393,20 +393,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-07-05T12:25:42+00:00" "time": "2025-08-01T08:46:24+00:00"
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.5.0", "version": "v5.6.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9" "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
"reference": "ae59794362fe85e051a58ad36b289443f57be7a9", "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -425,7 +425,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "5.0-dev" "dev-master": "5.x-dev"
} }
}, },
"autoload": { "autoload": {
@@ -449,9 +449,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0" "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1"
}, },
"time": "2025-05-31T08:24:38+00:00" "time": "2025-08-13T20:13:15+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@@ -892,16 +892,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.6.23", "version": "9.6.29",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95" "reference": "9ecfec57835a5581bc888ea7e13b51eb55ab9dd3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/43d2cb18d0675c38bd44982a5d1d88f6d53d8d95", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9ecfec57835a5581bc888ea7e13b51eb55ab9dd3",
"reference": "43d2cb18d0675c38bd44982a5d1d88f6d53d8d95", "reference": "9ecfec57835a5581bc888ea7e13b51eb55ab9dd3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -912,7 +912,7 @@
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-xml": "*", "ext-xml": "*",
"ext-xmlwriter": "*", "ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.13.1", "myclabs/deep-copy": "^1.13.4",
"phar-io/manifest": "^2.0.4", "phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1", "phar-io/version": "^3.2.1",
"php": ">=7.3", "php": ">=7.3",
@@ -923,11 +923,11 @@
"phpunit/php-timer": "^5.0.3", "phpunit/php-timer": "^5.0.3",
"sebastian/cli-parser": "^1.0.2", "sebastian/cli-parser": "^1.0.2",
"sebastian/code-unit": "^1.0.8", "sebastian/code-unit": "^1.0.8",
"sebastian/comparator": "^4.0.8", "sebastian/comparator": "^4.0.9",
"sebastian/diff": "^4.0.6", "sebastian/diff": "^4.0.6",
"sebastian/environment": "^5.1.5", "sebastian/environment": "^5.1.5",
"sebastian/exporter": "^4.0.6", "sebastian/exporter": "^4.0.8",
"sebastian/global-state": "^5.0.7", "sebastian/global-state": "^5.0.8",
"sebastian/object-enumerator": "^4.0.4", "sebastian/object-enumerator": "^4.0.4",
"sebastian/resource-operations": "^3.0.4", "sebastian/resource-operations": "^3.0.4",
"sebastian/type": "^3.2.1", "sebastian/type": "^3.2.1",
@@ -975,7 +975,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.23" "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.29"
}, },
"funding": [ "funding": [
{ {
@@ -999,7 +999,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-02T06:40:34+00:00" "time": "2025-09-24T06:29:11+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",
@@ -1170,16 +1170,16 @@
}, },
{ {
"name": "sebastian/comparator", "name": "sebastian/comparator",
"version": "4.0.8", "version": "4.0.9",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git", "url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "fa0f136dd2334583309d32b62544682ee972b51a" "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"reference": "fa0f136dd2334583309d32b62544682ee972b51a", "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1232,15 +1232,27 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues", "issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/comparator",
"type": "tidelift"
} }
], ],
"time": "2022-09-14T12:41:17+00:00" "time": "2025-08-10T06:51:50+00:00"
}, },
{ {
"name": "sebastian/complexity", "name": "sebastian/complexity",
@@ -1430,16 +1442,16 @@
}, },
{ {
"name": "sebastian/exporter", "name": "sebastian/exporter",
"version": "4.0.6", "version": "4.0.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git", "url": "https://github.com/sebastianbergmann/exporter.git",
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c",
"reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1495,28 +1507,40 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues", "issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/exporter",
"type": "tidelift"
} }
], ],
"time": "2024-03-02T06:33:00+00:00" "time": "2025-09-24T06:03:27+00:00"
}, },
{ {
"name": "sebastian/global-state", "name": "sebastian/global-state",
"version": "5.0.7", "version": "5.0.8",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git", "url": "https://github.com/sebastianbergmann/global-state.git",
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1559,15 +1583,27 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues", "issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/global-state",
"type": "tidelift"
} }
], ],
"time": "2024-03-02T06:35:11+00:00" "time": "2025-08-10T07:10:35+00:00"
}, },
{ {
"name": "sebastian/lines-of-code", "name": "sebastian/lines-of-code",
@@ -1740,16 +1776,16 @@
}, },
{ {
"name": "sebastian/recursion-context", "name": "sebastian/recursion-context",
"version": "4.0.5", "version": "4.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git", "url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" "reference": "539c6691e0623af6dc6f9c20384c120f963465a0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0",
"reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "reference": "539c6691e0623af6dc6f9c20384c120f963465a0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -1791,15 +1827,27 @@
"homepage": "https://github.com/sebastianbergmann/recursion-context", "homepage": "https://github.com/sebastianbergmann/recursion-context",
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues", "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
} }
], ],
"time": "2023-02-03T06:07:39+00:00" "time": "2025-08-10T06:57:39+00:00"
}, },
{ {
"name": "sebastian/resource-operations", "name": "sebastian/resource-operations",

View File

@@ -22,6 +22,7 @@ return array(
'IPLib\\Range\\Subnet' => $vendorDir . '/mlocati/ip-lib/src/Range/Subnet.php', 'IPLib\\Range\\Subnet' => $vendorDir . '/mlocati/ip-lib/src/Range/Subnet.php',
'IPLib\\Range\\Type' => $vendorDir . '/mlocati/ip-lib/src/Range/Type.php', 'IPLib\\Range\\Type' => $vendorDir . '/mlocati/ip-lib/src/Range/Type.php',
'IPLib\\Service\\BinaryMath' => $vendorDir . '/mlocati/ip-lib/src/Service/BinaryMath.php', 'IPLib\\Service\\BinaryMath' => $vendorDir . '/mlocati/ip-lib/src/Service/BinaryMath.php',
'IPLib\\Service\\NumberInChunks' => $vendorDir . '/mlocati/ip-lib/src/Service/NumberInChunks.php',
'IPLib\\Service\\RangesFromBoundaryCalculator' => $vendorDir . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php', 'IPLib\\Service\\RangesFromBoundaryCalculator' => $vendorDir . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
'IPLib\\Service\\UnsignedIntegerMath' => $vendorDir . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php', 'IPLib\\Service\\UnsignedIntegerMath' => $vendorDir . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
'Identicon\\Generator\\BaseGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php', 'Identicon\\Generator\\BaseGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',

View File

@@ -70,6 +70,7 @@ class ComposerStaticInitDontChange
'IPLib\\Range\\Subnet' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Subnet.php', 'IPLib\\Range\\Subnet' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Subnet.php',
'IPLib\\Range\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Type.php', 'IPLib\\Range\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Type.php',
'IPLib\\Service\\BinaryMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/BinaryMath.php', 'IPLib\\Service\\BinaryMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/BinaryMath.php',
'IPLib\\Service\\NumberInChunks' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/NumberInChunks.php',
'IPLib\\Service\\RangesFromBoundaryCalculator' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php', 'IPLib\\Service\\RangesFromBoundaryCalculator' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
'IPLib\\Service\\UnsignedIntegerMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php', 'IPLib\\Service\\UnsignedIntegerMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
'Identicon\\Generator\\BaseGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php', 'Identicon\\Generator\\BaseGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',

View File

@@ -3,7 +3,7 @@
'name' => 'privatebin/privatebin', 'name' => 'privatebin/privatebin',
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '3ba29ea29e04d8a16d64e0f49994ba416c1b008f', 'reference' => '06496a1b0e975b79c5a7abc0bd54b492ca264640',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),
@@ -20,9 +20,9 @@
'dev_requirement' => false, 'dev_requirement' => false,
), ),
'mlocati/ip-lib' => array( 'mlocati/ip-lib' => array(
'pretty_version' => '1.20.0', 'pretty_version' => '1.21.0',
'version' => '1.20.0.0', 'version' => '1.21.0.0',
'reference' => 'fd45fc3bf08ed6c7e665e2e70562082ac954afd4', 'reference' => 'b5d38cdcbfc1516604d821a1f3f4a1638f327267',
'type' => 'library', 'type' => 'library',
'install_path' => __DIR__ . '/../mlocati/ip-lib', 'install_path' => __DIR__ . '/../mlocati/ip-lib',
'aliases' => array(), 'aliases' => array(),
@@ -31,7 +31,7 @@
'privatebin/privatebin' => array( 'privatebin/privatebin' => array(
'pretty_version' => 'dev-master', 'pretty_version' => 'dev-master',
'version' => 'dev-master', 'version' => 'dev-master',
'reference' => '3ba29ea29e04d8a16d64e0f49994ba416c1b008f', 'reference' => '06496a1b0e975b79c5a7abc0bd54b492ca264640',
'type' => 'project', 'type' => 'project',
'install_path' => __DIR__ . '/../../', 'install_path' => __DIR__ . '/../../',
'aliases' => array(), 'aliases' => array(),

View File

@@ -110,11 +110,12 @@ interface AddressInterface
/** /**
* Get the address at a certain distance from this address. * Get the address at a certain distance from this address.
* *
* @param int $n the distance of the address (can be negative) * @param int|numeric-string $n the distance of the address (can be negative)
* *
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the final address would be invalid * @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or NULL if $n is neither an integer nor a string containing a valid integer, or if the final address would be invalid
* *
* @since 1.15.0 * @since 1.15.0
* @since 1.21.0 $n can also be a numeric string
* *
* @example passing 1 to the address 127.0.0.1 will result in 127.0.0.2 * @example passing 1 to the address 127.0.0.1 will result in 127.0.0.2
* @example passing -1 to the address 127.0.0.1 will result in 127.0.0.0 * @example passing -1 to the address 127.0.0.1 will result in 127.0.0.0

View File

@@ -6,6 +6,8 @@ use IPLib\ParseStringFlag;
use IPLib\Range\RangeInterface; use IPLib\Range\RangeInterface;
use IPLib\Range\Subnet; use IPLib\Range\Subnet;
use IPLib\Range\Type as RangeType; use IPLib\Range\Type as RangeType;
use IPLib\Service\BinaryMath;
use IPLib\Service\NumberInChunks;
/** /**
* An IPv4 address. * An IPv4 address.
@@ -456,28 +458,24 @@ class IPv4 implements AddressInterface
*/ */
public function getAddressAtOffset($n) public function getAddressAtOffset($n)
{ {
if (!is_int($n)) { if (is_int($n)) {
$thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_BYTES);
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
$thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_BYTES);
} else {
return null;
}
$myBytes = $this->getBytes();
while (isset($myBytes[1]) && $myBytes[0] === 0) {
array_shift($myBytes);
}
$myChunks = new NumberInChunks(false, $myBytes, NumberInChunks::CHUNKSIZE_BYTES);
$result = $myChunks->add($thatChunks);
if ($result->negative || count($result->chunks) > 4) {
return null; return null;
} }
$boundary = 256; return static::fromBytes(array_pad($result->chunks, -4, 0));
$mod = $n;
$bytes = $this->getBytes();
for ($i = count($bytes) - 1; $i >= 0; $i--) {
$tmp = ($bytes[$i] + $mod) % $boundary;
$mod = (int) floor(($bytes[$i] + $mod) / $boundary);
if ($tmp < 0) {
$tmp += $boundary;
}
$bytes[$i] = $tmp;
}
if ($mod !== 0) {
return null;
}
return static::fromBytes($bytes);
} }
/** /**

View File

@@ -6,6 +6,8 @@ use IPLib\ParseStringFlag;
use IPLib\Range\RangeInterface; use IPLib\Range\RangeInterface;
use IPLib\Range\Subnet; use IPLib\Range\Subnet;
use IPLib\Range\Type as RangeType; use IPLib\Range\Type as RangeType;
use IPLib\Service\BinaryMath;
use IPLib\Service\NumberInChunks;
/** /**
* An IPv6 address. * An IPv6 address.
@@ -549,28 +551,24 @@ class IPv6 implements AddressInterface
*/ */
public function getAddressAtOffset($n) public function getAddressAtOffset($n)
{ {
if (!is_int($n)) { if (is_int($n)) {
$thatChunks = NumberInChunks::fromInteger($n, NumberInChunks::CHUNKSIZE_WORDS);
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
$thatChunks = NumberInChunks::fromNumericString($s, NumberInChunks::CHUNKSIZE_WORDS);
} else {
return null;
}
$myWords = $this->getWords();
while (isset($myWords[1]) && $myWords[0] === 0) {
array_shift($myWords);
}
$myChunks = new NumberInChunks(false, $myWords, NumberInChunks::CHUNKSIZE_WORDS);
$result = $myChunks->add($thatChunks);
if ($result->negative || count($result->chunks) > 8) {
return null; return null;
} }
$boundary = 0x10000; return static::fromWords(array_pad($result->chunks, -8, 0));
$mod = $n;
$words = $this->getWords();
for ($i = count($words) - 1; $i >= 0; $i--) {
$tmp = ($words[$i] + $mod) % $boundary;
$mod = (int) floor(($words[$i] + $mod) / $boundary);
if ($tmp < 0) {
$tmp += $boundary;
}
$words[$i] = $tmp;
}
if ($mod !== 0) {
return null;
}
return static::fromWords($words);
} }
/** /**
@@ -645,7 +643,7 @@ class IPv6 implements AddressInterface
} }
$myWords = $this->getWords(); $myWords = $this->getWords();
$otherWords = $other->getWords(); $otherWords = $other->getWords();
$sum = array_fill(0, 7, 0); $sum = array_fill(0, 8, 0);
$carry = 0; $carry = 0;
for ($index = 7; $index >= 0; $index--) { for ($index = 7; $index >= 0; $index--) {
$word = $myWords[$index] + $otherWords[$index] + $carry; $word = $myWords[$index] + $otherWords[$index] + $carry;

View File

@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
use IPLib\Address\IPv6; use IPLib\Address\IPv6;
use IPLib\Address\Type as AddressType; use IPLib\Address\Type as AddressType;
use IPLib\Factory; use IPLib\Factory;
use IPLib\Service\BinaryMath;
use OutOfBoundsException; use OutOfBoundsException;
/** /**
@@ -59,17 +60,26 @@ abstract class AbstractRange implements RangeInterface
*/ */
public function getAddressAtOffset($n) public function getAddressAtOffset($n)
{ {
if (!is_int($n)) { if (is_int($n)) {
$positive = $n >= 0;
if ($positive === false) {
$nPlus1 = $n + 1;
}
} elseif (($s = BinaryMath::getInstance()->normalizeIntegerString($n)) !== '') {
$n = $s;
$positive = $n[0] !== '-';
if ($positive === false) {
$nPlus1 = BinaryMath::getInstance()->add1ToIntegerString($n);
}
} else {
return null; return null;
} }
if ($positive) {
$address = null;
if ($n >= 0) {
$start = Factory::parseAddressString($this->getComparableStartString()); $start = Factory::parseAddressString($this->getComparableStartString());
$address = $start->getAddressAtOffset($n); $address = $start->getAddressAtOffset($n);
} else { } else {
$end = Factory::parseAddressString($this->getComparableEndString()); $end = Factory::parseAddressString($this->getComparableEndString());
$address = $end->getAddressAtOffset($n + 1); $address = $end->getAddressAtOffset($nPlus1);
} }
if ($address === null) { if ($address === null) {

View File

@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
use IPLib\Address\IPv6; use IPLib\Address\IPv6;
use IPLib\Address\Type as AddressType; use IPLib\Address\Type as AddressType;
use IPLib\ParseStringFlag; use IPLib\ParseStringFlag;
use IPLib\Service\BinaryMath;
/** /**
* Represents an address range in pattern format (only ending asterisks are supported). * Represents an address range in pattern format (only ending asterisks are supported).
@@ -304,7 +305,21 @@ class Pattern extends AbstractRange
$maxPrefix = $fromAddress::getNumberOfBits(); $maxPrefix = $fromAddress::getNumberOfBits();
$prefix = $this->getNetworkPrefix(); $prefix = $this->getNetworkPrefix();
return pow(2, ($maxPrefix - $prefix)); return pow(2, $maxPrefix - $prefix);
}
/**
* {@inheritdoc}
*
* @see \IPLib\Range\RangeInterface::getExactSize()
*/
public function getExactSize()
{
$fromAddress = $this->fromAddress;
$maxPrefix = $fromAddress::getNumberOfBits();
$prefix = $this->getNetworkPrefix();
return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
} }
/** /**

View File

@@ -46,11 +46,12 @@ interface RangeInterface
/** /**
* Get the address at a certain offset of this range. * Get the address at a certain offset of this range.
* *
* @param int $n the offset of the address (support negative offset) * @param int|numeric-string $n the offset of the address (support negative offset)
* *
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the offset out of range * @return \IPLib\Address\AddressInterface|null return NULL if $n is neither an integer nor a string containing a valid integer, or if the offset out of range
* *
* @since 1.15.0 * @since 1.15.0
* @since 1.21.0 $n can also be a numeric string
* *
* @example passing 256 to the range 127.0.0.0/16 will result in 127.0.1.0 * @example passing 256 to the range 127.0.0.0/16 will result in 127.0.1.0
* @example passing -1 to the range 127.0.1.0/16 will result in 127.0.255.255 * @example passing -1 to the range 127.0.1.0/16 will result in 127.0.255.255
@@ -150,14 +151,23 @@ interface RangeInterface
public function getReverseDNSLookupName(); public function getReverseDNSLookupName();
/** /**
* Get the count of addresses this IP range contains. * Get the count of addresses contained in this IP range (possibly approximated).
* *
* @return int|float Return float as for huge IPv6 networks, int is not enough * @return int|float If the number of addresses exceeds PHP_INT_MAX a float containing an approximation will be returned
* *
* @since 1.16.0 * @since 1.16.0
*/ */
public function getSize(); public function getSize();
/**
* Get the exact count of addresses contained in this IP range.
*
* @return int|numeric-string If the number of addresses exceeds PHP_INT_MAX a string containing the exact number of addresses will be returned
*
* @since 1.21.0
*/
public function getExactSize();
/** /**
* Get the "network prefix", that is how many bits of the address are dedicated to the network portion. * Get the "network prefix", that is how many bits of the address are dedicated to the network portion.
* *

View File

@@ -237,6 +237,16 @@ class Single extends AbstractRange
return 1; return 1;
} }
/**
* {@inheritdoc}
*
* @see \IPLib\Range\RangeInterface::getExactSize()
*/
public function getExactSize()
{
return 1;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *

View File

@@ -7,6 +7,7 @@ use IPLib\Address\IPv4;
use IPLib\Address\Type as AddressType; use IPLib\Address\Type as AddressType;
use IPLib\Factory; use IPLib\Factory;
use IPLib\ParseStringFlag; use IPLib\ParseStringFlag;
use IPLib\Service\BinaryMath;
/** /**
* Represents an address range in subnet format (eg CIDR). * Represents an address range in subnet format (eg CIDR).
@@ -348,6 +349,20 @@ class Subnet extends AbstractRange
$maxPrefix = $fromAddress::getNumberOfBits(); $maxPrefix = $fromAddress::getNumberOfBits();
$prefix = $this->getNetworkPrefix(); $prefix = $this->getNetworkPrefix();
return pow(2, ($maxPrefix - $prefix)); return pow(2, $maxPrefix - $prefix);
}
/**
* {@inheritdoc}
*
* @see \IPLib\Range\RangeInterface::getExactSize()
*/
public function getExactSize()
{
$fromAddress = $this->fromAddress;
$maxPrefix = $fromAddress::getNumberOfBits();
$prefix = $this->getNetworkPrefix();
return BinaryMath::getInstance()->pow2string($maxPrefix - $prefix);
} }
} }

View File

@@ -120,29 +120,29 @@ class Type
case static::T_UNSPECIFIED: case static::T_UNSPECIFIED:
return 'Unspecified/unknown address'; return 'Unspecified/unknown address';
case static::T_RESERVED: case static::T_RESERVED:
return 'Reserved/internal use only'; return 'Reserved/internal use only';
case static::T_THISNETWORK: case static::T_THISNETWORK:
return 'Refer to source hosts on "this" network'; return 'Refer to source hosts on "this" network';
case static::T_LOOPBACK: case static::T_LOOPBACK:
return 'Internet host loopback address'; return 'Internet host loopback address';
case static::T_ANYCASTRELAY: case static::T_ANYCASTRELAY:
return 'Relay anycast address'; return 'Relay anycast address';
case static::T_LIMITEDBROADCAST: case static::T_LIMITEDBROADCAST:
return '"Limited broadcast" destination address'; return '"Limited broadcast" destination address';
case static::T_MULTICAST: case static::T_MULTICAST:
return 'Multicast address assignments - Indentify a group of interfaces'; return 'Multicast address assignments - Indentify a group of interfaces';
case static::T_LINKLOCAL: case static::T_LINKLOCAL:
return '"Link local" address, allocated for communication between hosts on a single link'; return '"Link local" address, allocated for communication between hosts on a single link';
case static::T_LINKLOCAL_UNICAST: case static::T_LINKLOCAL_UNICAST:
return 'Link local unicast / Linked-scoped unicast'; return 'Link local unicast / Linked-scoped unicast';
case static::T_DISCARDONLY: case static::T_DISCARDONLY:
return 'Discard only'; return 'Discard only';
case static::T_DISCARD: case static::T_DISCARD:
return 'Discard'; return 'Discard';
case static::T_PRIVATENETWORK: case static::T_PRIVATENETWORK:
return 'For use in private networks'; return 'For use in private networks';
case static::T_PUBLIC: case static::T_PUBLIC:
return 'Public address'; return 'Public address';
case static::T_CGNAT: case static::T_CGNAT:
return 'Carrier-grade NAT'; return 'Carrier-grade NAT';
default: default:

View File

@@ -9,6 +9,20 @@ namespace IPLib\Service;
*/ */
class BinaryMath class BinaryMath
{ {
private static $instance;
/**
* @return \IPLib\Service\BinaryMath
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/** /**
* Trim the leading zeroes from a non-negative integer represented in binary form. * Trim the leading zeroes from a non-negative integer represented in binary form.
* *
@@ -97,6 +111,104 @@ class BinaryMath
return $result; return $result;
} }
/**
* Compute 2 raised to the given exponent.
*
* If the result fits into a native PHP integer, an int is returned.
* If the result exceeds PHP_INT_MAX, a string containing the exact decimal representation is returned.
*
* @param int $exponent The non-negative exponent
*
* @return int|string
*/
public function pow2string($exponent)
{
if ($exponent < PHP_INT_SIZE * 8 - 1) {
return 1 << $exponent;
}
$digits = array(1);
for ($i = 0; $i < $exponent; $i++) {
$carry = 0;
foreach ($digits as $index => $digit) {
$product = $digit * 2 + $carry;
$digits[$index] = $product % 10;
$carry = (int) ($product / 10);
}
if ($carry !== 0) {
$digits[] = $carry;
}
}
return implode('', array_reverse($digits));
}
/**
* @param numeric-string|mixed $value
*
* @return string empty string if $value is not a valid numeric string
*/
public function normalizeIntegerString($value)
{
if (!is_string($value) || $value === '') {
return '';
}
$sign = $value[0];
if ($sign === '-' || $sign === '+') {
$value = substr($value, 1);
}
$matches = null;
if (!preg_match('/^0*([0-9]+)$/', $value, $matches)) {
return '';
}
return ($sign === '-' && $matches[1] !== '0' ? $sign : '') . $matches[1];
}
/**
* @param numeric-string $value a string that has been normalized with normalizeIntegerString()
*
* @return string
*/
public function add1ToIntegerString($value)
{
if ($value[0] === '-') {
if ($value === '-1') {
return '0';
}
$digits = str_split(substr($value, 1));
$i = count($digits) - 1;
while ($i >= 0) {
if ($digits[$i] !== '0') {
$digits[$i] = (string) ((int) $digits[$i] - 1);
break;
}
$digits[$i] = '9';
$i--;
}
$imploded = implode('', $digits);
if ($imploded[0] === '0') {
$imploded = substr($imploded, 1);
}
return '-' . $imploded;
}
$digits = str_split($value);
$carry = 1;
for ($i = count($digits) - 1; $i >= 0; $i--) {
$sum = (int) $digits[$i] + $carry;
$digits[$i] = (string) ($sum % 10);
$carry = (int) ($sum / 10);
if ($carry === 0) {
break;
}
if ($i === 0) {
array_unshift($digits, (string) $carry);
}
}
return implode('', $digits);
}
/** /**
* Zero-padding of two non-negative integers represented in binary form, so that they have the same length. * Zero-padding of two non-negative integers represented in binary form, so that they have the same length.
* *

View File

@@ -0,0 +1,253 @@
<?php
namespace IPLib\Service;
use InvalidArgumentException;
/**
* @internal
*
* @readonly
*/
class NumberInChunks
{
const CHUNKSIZE_BYTES = 8;
const CHUNKSIZE_WORDS = 16;
/**
* @var bool
*/
public $negative;
/**
* @var int[]
*/
public $chunks;
/**
* @var int
*/
public $chunkSize;
/**
* @param bool $negative
* @param int[] $chunks
* @param int $chunkSize
*/
public function __construct($negative, array $chunks, $chunkSize)
{
$this->negative = $negative;
$this->chunks = $chunks;
$this->chunkSize = $chunkSize;
}
/**
* @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this
*
* @return \IPLib\Service\NumberInChunks
*/
public function negate()
{
return new self($this->chunks === array(0) ? false : !$this->negative, $this->chunks, $this->chunkSize);
}
/**
* @throws \InvalidArgumentException if $other has a $chunkSize that's not the same as the $chunkSize of this
*
* @return \IPLib\Service\NumberInChunks
*/
public function add(NumberInChunks $that)
{
if ($this->chunkSize !== $that->chunkSize) {
throw new InvalidArgumentException('Incompatible chunk size');
}
if ($this->negative === $that->negative) {
return new self($this->negative, self::addChunks($this->chunks, $that->chunks, $this->chunkSize), $this->chunkSize);
}
if ($that->negative) {
list($negative, $chunks) = self::substractChunks($this->chunks, $that->chunks, $this->chunkSize);
} else {
list($negative, $chunks) = self::substractChunks($that->chunks, $this->chunks, $this->chunkSize);
}
return new self($negative, $chunks, $this->chunkSize);
}
/**
* @param int $int
* @param int $chunkSize
*
* @return \IPLib\Service\NumberInChunks
*/
public static function fromInteger($int, $chunkSize)
{
if ($int === 0) {
return new self(false, array(0), $chunkSize);
}
$negative = $int < 0;
if ($negative) {
$positiveInt = -$int;
if (is_float($positiveInt)) { // -PHP_INT_MIN is bigger than PHP_INT_MAX
return self::fromNumericString((string) $int, $chunkSize);
}
$int = $positiveInt;
}
$bitMask = (1 << $chunkSize) - 1;
$chunks = array();
while ($int !== 0) {
$chunks[] = $int & $bitMask;
$int >>= $chunkSize;
}
return new self($negative, array_reverse($chunks), $chunkSize);
}
/**
* @param string $numericString a string normalized with BinaryMath::normalizeIntegerString()
* @param int $chunkSize
*
* @return \IPLib\Service\NumberInChunks
*/
public static function fromNumericString($numericString, $chunkSize)
{
if ($numericString === '0') {
return new self(false, array(0), $chunkSize);
}
$negative = $numericString[0] === '-';
if ($negative) {
$numericString = substr($numericString, 1);
}
$chunks = array();
while ($numericString !== '0') {
$chunks[] = self::modulo($numericString, $chunkSize);
$numericString = self::divide($numericString, $chunkSize);
}
return new self($negative, array_reverse($chunks), $chunkSize);
}
/**
* @param string $numericString
* @param int $chunkSize
*
* @return int
*/
private static function modulo($numericString, $chunkSize)
{
$divisor = 1 << $chunkSize;
$carry = 0;
$len = strlen($numericString);
for ($i = 0; $i < $len; $i++) {
$digit = (int) $numericString[$i];
$carry = ($carry * 10 + $digit) % $divisor;
}
return $carry;
}
/**
* @param string $numericString
* @param int $chunkSize
*
* @return string
*/
private static function divide($numericString, $chunkSize)
{
$divisor = 1 << $chunkSize;
$quotient = '';
$carry = 0;
$len = strlen($numericString);
for ($i = 0; $i < $len; $i++) {
$digit = (int) $numericString[$i];
$value = $carry * 10 + $digit;
$quotient .= (string) ($value >> $chunkSize);
$carry = $value % $divisor;
}
return ltrim($quotient, '0') ?: '0';
}
/**
* @param int[] $addend1
* @param int[] $addend2
* @param int $chunkSize
*
* @return int[]
*/
private static function addChunks(array $addend1, array $addend2, $chunkSize)
{
$divisor = 1 << $chunkSize;
$result = array();
$carry = 0;
while ($addend1 !== array() || $addend2 !== array()) {
$sum = $carry + (array_pop($addend1) ?: 0) + (array_pop($addend2) ?: 0);
$result[] = $sum % $divisor;
$carry = $sum >> $chunkSize;
}
if ($carry !== 0) {
$result[] = $carry;
}
return array_reverse($result);
}
/**
* @param int[] $minuend
* @param int[] $subtrahend
* @param int $chunkSize
*
* @return array
*/
private static function substractChunks(array $minuend, array $subtrahend, $chunkSize)
{
$minuendCount = count($minuend);
$subtrahendCount = count($subtrahend);
if ($minuendCount > $subtrahendCount) {
$count = $minuendCount;
$negative = false;
} elseif ($minuendCount < $subtrahendCount) {
$count = $subtrahendCount;
$negative = true;
} else {
$count = $minuendCount;
$negative = false;
for ($i = 0; $i < $count; $i++) {
$delta = $minuend[$i] - $subtrahend[$i];
if ($delta === 0) {
continue;
}
if ($delta < 0) {
$negative = true;
}
break;
}
}
if ($negative) {
list($minuend, $subtrahend) = array($subtrahend, $minuend);
}
$subtrahend = array_pad($subtrahend, -$count, 0);
$borrowValue = 1 << $chunkSize;
$result = array();
$borrow = 0;
for ($i = $count - 1; $i >= 0; $i--) {
$value = $minuend[$i] - $subtrahend[$i] - $borrow;
if ($value < 0) {
$value += $borrowValue;
$borrow = 1;
} else {
$borrow = 0;
}
$result[] = $value;
}
while (isset($result[1])) {
$value = array_pop($result);
if ($value !== 0) {
$result[] = $value;
break;
}
}
return array($negative, array_reverse($result));
}
}

View File

@@ -50,7 +50,7 @@ class RangesFromBoundaryCalculator
*/ */
public function __construct($numBits) public function __construct($numBits)
{ {
$this->math = new BinaryMath(); $this->math = BinaryMath::getInstance();
$this->setNumBits($numBits); $this->setNumBits($numBits);
} }