소스 검색

Merge branch 'master' into fix/openclaw-20260427

El RIDO 3 달 전
부모
커밋
fd7c352026
36개의 변경된 파일319개의 추가작업 그리고 177개의 파일을 삭제
  1. 0 2
      .github/workflows/snyk-scan.yml
  2. 1 1
      .github/workflows/test-results.yml
  3. 1 1
      CHANGELOG.md
  4. 1 0
      composer.json
  5. 10 15
      composer.lock
  6. 2 2
      js/common.js
  7. 1 1
      js/eslint.config.js
  8. 0 1
      js/purify-3.3.2.js
  9. 1 0
      js/purify-3.4.1.js
  10. BIN
      js/zlib-1.3.1.wasm
  11. 0 0
      js/zlib-1.3.2.js
  12. BIN
      js/zlib-1.3.2.wasm
  13. 18 42
      js/zlib.js
  14. 3 2
      lib/Configuration.php
  15. 44 6
      lib/View.php
  16. 3 2
      tpl/bootstrap.php
  17. 3 2
      tpl/bootstrap5.php
  18. 1 1
      tst/Bootstrap.php
  19. 8 8
      vendor/composer/installed.php
  20. 3 1
      vendor/mlocati/ip-lib/src/Address/AddressInterface.php
  21. 18 7
      vendor/mlocati/ip-lib/src/Address/IPv4.php
  22. 26 11
      vendor/mlocati/ip-lib/src/Address/IPv6.php
  23. 2 2
      vendor/mlocati/ip-lib/src/Address/Type.php
  24. 69 25
      vendor/mlocati/ip-lib/src/Factory.php
  25. 21 13
      vendor/mlocati/ip-lib/src/Range/AbstractRange.php
  26. 17 2
      vendor/mlocati/ip-lib/src/Range/Pattern.php
  27. 4 2
      vendor/mlocati/ip-lib/src/Range/RangeInterface.php
  28. 2 0
      vendor/mlocati/ip-lib/src/Range/Single.php
  29. 14 9
      vendor/mlocati/ip-lib/src/Range/Subnet.php
  30. 2 2
      vendor/mlocati/ip-lib/src/Range/Type.php
  31. 22 8
      vendor/mlocati/ip-lib/src/Service/BinaryMath.php
  32. 3 2
      vendor/mlocati/ip-lib/src/Service/NumberInChunks.php
  33. 9 2
      vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php
  34. 4 2
      vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php
  35. 1 1
      vendor/symfony/polyfill-php80/Php80.php
  36. 5 2
      vendor/symfony/polyfill-php80/PhpToken.php

+ 0 - 2
.github/workflows/snyk-scan.yml

@@ -25,8 +25,6 @@ jobs:
       github.event.pull_request.author_association == 'OWNER' )
     steps:
       - uses: actions/checkout@v6
-      - name: Install Google Cloud Storage
-        run: composer require --no-update google/cloud-storage && composer update --no-dev
       - name: Run Snyk to check for vulnerabilities
         uses: snyk/actions/php@master
         continue-on-error: true # To make sure that SARIF upload gets called

+ 1 - 1
.github/workflows/test-results.yml

@@ -25,7 +25,7 @@ jobs:
 
     steps:
        - name: Download and Extract Artifacts
-         uses: dawidd6/action-download-artifact@8305c0f1062bb0d184d09ef4493ecb9288447732
+         uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151
          with:
           run_id: ${{ github.event.workflow_run.id }}
           path: artifacts

+ 1 - 1
CHANGELOG.md

@@ -4,7 +4,7 @@
 * ADDED: Translations for Swedish & Persian
 * CHANGED: Deduplicate JSON error message translations
 * CHANGED: Refactored translation of exception messages
-* CHANGED: Upgrading libraries to: DOMpurify 3.3.2, ip-lib 1.22.0 & polyfill-php80 1.34.0
+* CHANGED: Upgrading libraries to: DOMpurify 3.4.1, ip-lib 1.22.0, polyfill-php80 1.34.0 & zlib 1.3.2
 * CHANGED: Remove obsolete X-XSS-Protection header (#1825)
 * FIXED: Some exceptions not getting translated
 * FIXED: Attachment disappears after a "paste" in the message area (#1731)

+ 1 - 0
composer.json

@@ -44,6 +44,7 @@
 	},
 	"config" : {
 		"audit": {
+			"block-insecure": false,
 			"ignore": {
 				"CVE-2025-45769": "disputed on the basis that key lengths are expected to be set by an application, not by this library"
 			}

+ 10 - 15
composer.lock

@@ -215,7 +215,7 @@
             "version": "2.0.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/yzalis/Identicon.git",
+                "url": "https://github.com/yzalis/Identicon",
                 "reference": "ff5ed090129cab9bfa2a322857d4a01d107aa0ae"
             },
             "dist": {
@@ -260,11 +260,6 @@
                 "identicon",
                 "image"
             ],
-            "support": {
-                "issues": "https://github.com/yzalis/Identicon/issues",
-                "source": "https://github.com/yzalis/Identicon/tree/master"
-            },
-            "abandoned": true,
             "time": "2019-10-14T09:30:57+00:00"
         }
     ],
@@ -896,16 +891,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "9.6.33",
+            "version": "9.6.34",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "fea06253ecc0a32faf787bd31b261f56f351d049"
+                "reference": "b36f02317466907a230d3aa1d34467041271ef4a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fea06253ecc0a32faf787bd31b261f56f351d049",
-                "reference": "fea06253ecc0a32faf787bd31b261f56f351d049",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a",
+                "reference": "b36f02317466907a230d3aa1d34467041271ef4a",
                 "shasum": ""
             },
             "require": {
@@ -979,7 +974,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.33"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34"
             },
             "funding": [
                 {
@@ -1003,7 +998,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2026-01-27T05:25:09+00:00"
+            "time": "2026-01-27T05:45:00+00:00"
         },
         {
             "name": "sebastian/cli-parser",
@@ -2069,15 +2064,15 @@
     ],
     "aliases": [],
     "minimum-stability": "stable",
-    "stability-flags": {},
+    "stability-flags": [],
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
         "php": "^7.4 || ^8.0"
     },
-    "platform-dev": {},
+    "platform-dev": [],
     "platform-overrides": {
         "php": "7.4"
     },
-    "plugin-api-version": "2.9.0"
+    "plugin-api-version": "2.3.0"
 }

+ 2 - 2
js/common.js

@@ -10,12 +10,12 @@ global.WebCrypto = require('@peculiar/webcrypto').Crypto;
 
 // application libraries to test
 global.$ = global.jQuery = require('./jquery-3.7.1');
-global.zlib = require('./zlib-1.3.1-2').zlib;
+global.zlib = require('./zlib').zlib;
 require('./prettify');
 global.prettyPrint = window.PR.prettyPrint;
 global.prettyPrintOne = window.PR.prettyPrintOne;
 global.showdown = require('./showdown-2.1.0');
-global.DOMPurify = require('./purify-3.3.2');
+global.DOMPurify = require('./purify-3.4.1');
 global.baseX = require('./base-x-5.0.1').baseX;
 global.Legacy = require('./legacy').Legacy;
 require('./privatebin');

+ 1 - 1
js/eslint.config.js

@@ -1,7 +1,7 @@
 const globals = require('globals');
 const { globalIgnores } = require('eslint/config')
 
-module.exports = [globalIgnores(["./*.js", "!./privatebin.js"]), {
+module.exports = [globalIgnores(["./*.*js", "!./privatebin.js"]), {
     languageOptions: {
         globals: {
             ...globals.amd,

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 1
js/purify-3.3.2.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 0
js/purify-3.4.1.js


BIN
js/zlib-1.3.1.wasm


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 0
js/zlib-1.3.2.js


BIN
js/zlib-1.3.2.wasm


+ 18 - 42
js/zlib-1.3.1-2.js → js/zlib.js

@@ -9,37 +9,22 @@
         const COMPRESSION_LEVEL = 7;
         const NO_ZLIB_HEADER = -1;
         const CHUNK_SIZE = 32 * 1024;
-        const map = {};
-        const memory = new WebAssembly.Memory({
-            initial: 1,
-            maximum: 1024, // 64MB
-        });
-        const env = {
-            memory,
-            writeToJs(ptr, size) {
-                const o = map[ptr];
-                o.onData(new Uint8Array(memory.buffer, dstPtr, size));
-            },
-            _abort: errno => { console.error(`Error: ${errno}`) },
-            _grow: () => { },
-        };
-        const ins = (await WebAssembly.instantiateStreaming(fetch('js/zlib-1.3.1.wasm'), { env })).instance;
-
-        const srcPtr = ins.exports._malloc(CHUNK_SIZE);
-        const dstPtr = ins.exports._malloc(CHUNK_SIZE);
+        const createModule = (await import('./zlib-1.3.2.js')).default;
+        const Module = await createModule({map: {}});
+        const srcPtr = Module.__malloc(CHUNK_SIZE);
+        const dstPtr = Module.__malloc(CHUNK_SIZE);
 
         class RawDef {
             constructor() {
-                this.zstreamPtr = ins.exports._createDeflateContext(COMPRESSION_LEVEL, NO_ZLIB_HEADER);
-                map[this.zstreamPtr] = this;
+                this.zstreamPtr = Module.__createDeflateContext(COMPRESSION_LEVEL, NO_ZLIB_HEADER);
+                Module.map[this.zstreamPtr] = this;
                 this.offset = 0;
                 this.buff = new Uint8Array(CHUNK_SIZE);
             }
 
             deflate(chunk, flush) {
-                const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
-                src.set(chunk);
-                ins.exports._deflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE, flush);
+                Module.HEAPU8.set(chunk, srcPtr);
+                Module.__deflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE, flush);
             }
 
             onData(chunk) {
@@ -53,32 +38,27 @@
             }
 
             destroy() {
-                ins.exports._freeDeflateContext(this.zstreamPtr);
-                delete map[this.zstreamPtr];
+                Module.__freeDeflateContext(this.zstreamPtr);
+                delete Module.map[this.zstreamPtr];
                 this.buff = null;
             }
 
             getBuffer() {
-                const res = new Uint8Array(this.offset);
-                for (let i = 0; i < this.offset; ++i) {
-                    res[i] = this.buff[i];
-                }
-                return res;
+                return this.buff.slice(0, this.offset);
             }
         }
 
         class RawInf {
             constructor() {
-                this.zstreamPtr = ins.exports._createInflateContext(NO_ZLIB_HEADER);
-                map[this.zstreamPtr] = this;
+                this.zstreamPtr = Module.__createInflateContext(NO_ZLIB_HEADER);
+                Module.map[this.zstreamPtr] = this;
                 this.offset = 0;
                 this.buff = new Uint8Array(CHUNK_SIZE);
             }
 
             inflate(chunk) {
-                const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
-                src.set(chunk);
-                ins.exports._inflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE);
+                Module.HEAPU8.set(chunk, srcPtr);
+                Module.__inflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE);
             }
 
             onData(chunk) {
@@ -92,17 +72,13 @@
             }
 
             destroy() {
-                ins.exports._freeInflateContext(this.zstreamPtr);
-                delete map[this.zstreamPtr];
+                Module.__freeInflateContext(this.zstreamPtr);
+                delete Module.map[this.zstreamPtr];
                 this.buff = null;
             }
 
             getBuffer() {
-                const res = new Uint8Array(this.offset);
-                for (let i = 0; i < this.offset; ++i) {
-                    res[i] = this.buff[i];
-                }
-                return res;
+                return this.buff.slice(0, this.offset);
             }
         }
 

+ 3 - 2
lib/Configuration.php

@@ -123,9 +123,10 @@ class Configuration
             'js/legacy.js'           => 'sha512-RQEo1hxpNc37i+jz/D9/JiAZhG8GFx3+SNxjYnI7jUgirDIqrCSj6QPAAZeaidditcWzsJ3jxfEj5lVm7ZwTRQ==',
             'js/prettify.js'         => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
             'js/privatebin.js'       => 'sha512-6SwOJniNN8RBmAK7yCt4ly2qYyH8OALxB74/K1AJgw+YnZgRCfTDVq1qY1K5Y2QCxCODGGTpAjTqQRExzCqV7g==',
-            'js/purify-3.3.2.js'     => 'sha512-I6igPVpf3xNghG92mujwqB6Zi3LpUTsni4bRuLnMThEGH6BDbsumv7373+AXHzA4OUlxGsym8ZxKFHy4xjYvkQ==',
+            'js/purify-3.4.1.js'     => 'sha512-280a/Vb6fVFsYaeRrkuDp4EDmdYlt2XS+dlDEO/U9qljPrAraA2bIzHTNmP+9dpwPDDwTML+RS+h5iaagPwTzA==',
             'js/showdown-2.1.0.js'   => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
-            'js/zlib-1.3.1-2.js'     => 'sha512-4gT+v+BkBqdVBbKOO4qKGOAzuay+v1FmOLksS+bMgQ08Oo4xEb3X48Xq1Kv2b4HtiCQA7xq9dFRzxal7jmQI7w==',
+            'js/zlib-1.3.2.js'       => 'sha512-RAhJgxg9siMIA8ky4c10Rc2zUgnK80olHB8Tt1IOYWY4Eh1WmrviQkDn+sgBlb38ZHq3tzufGC41kP360gmosQ==',
+            'js/zlib.js'             => 'sha512-QOaEwssHqHRRcWJ2Un3Kl2Zhyprzl7T8zmsKN2FppFxW3VR+8UChYOx2iuL0HbXK42fuBWJm5PNQJxufulrt/w==',
         ),
     );
 

+ 44 - 6
lib/View.php

@@ -62,6 +62,48 @@ class View
         include $path;
     }
 
+    /**
+     * get cache buster query string
+     *
+     * if the file isn't versioned (ends in a digit), adds our own version as a query string
+     *
+     * @access private
+     * @param  string $file
+     */
+    private function _getCacheBuster($file)
+    {
+        if ((bool) preg_match('#[0-9]\.m?js$#', (string) $file)) {
+            return '';
+        }
+        return '?' . rawurlencode($this->_variables['VERSION']);
+    }
+
+    /**
+     * get SRI hash for given file
+     *
+     * @access private
+     * @param  string $file
+     */
+    private function _getSri($file)
+    {
+        if (array_key_exists($file, $this->_variables['SRI'])) {
+            return ' integrity="' . $this->_variables['SRI'][$file] . '"';
+        }
+        return '';
+    }
+
+    /**
+     * echo module preload link tag incl. SRI hash for given script file
+     *
+     * @access private
+     * @param  string $file
+     */
+    private function _linkTag($file)
+    {
+        echo '<link rel="modulepreload" href="', $file,
+        $this->_getCacheBuster($file), '"', $this->_getSri($file), ' />', PHP_EOL;
+    }
+
     /**
      * echo script tag incl. SRI hash for given script file
      *
@@ -71,13 +113,9 @@ class View
      */
     private function _scriptTag($file, $attributes = '')
     {
-        $sri = array_key_exists($file, $this->_variables['SRI']) ?
-            ' integrity="' . $this->_variables['SRI'][$file] . '"' : '';
-        // if the file isn't versioned (ends in a digit), add our own version
-        $cacheBuster = (bool) preg_match('#[0-9]\.js$#', (string) $file) ?
-            '' : '?' . rawurlencode($this->_variables['VERSION']);
         echo '<script ', $attributes,
         ' type="text/javascript" data-cfasync="false" src="', $file,
-        $cacheBuster, '"', $sri, ' crossorigin="anonymous"></script>', PHP_EOL;
+        $this->_getCacheBuster($file), '"', $this->_getSri($file),
+        ' crossorigin="anonymous"></script>', PHP_EOL;
     }
 }

+ 3 - 2
tpl/bootstrap.php

@@ -42,6 +42,7 @@ if ($SYNTAXHIGHLIGHTING) :
 endif;
 ?>
 		<noscript><link type="text/css" rel="stylesheet" href="css/noscript.css" /></noscript>
+		<?php $this->_linkTag('js/zlib-1.3.2.js'); ?>
 		<?php $this->_scriptTag('js/jquery-3.7.1.js', 'defer'); ?>
 <?php
 if ($QRCODE) :
@@ -50,7 +51,7 @@ if ($QRCODE) :
 <?php
 endif;
 ?>
-		<?php $this->_scriptTag('js/zlib-1.3.1-2.js', 'defer'); ?>
+		<?php $this->_scriptTag('js/zlib.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/base-x-5.0.1.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/bootstrap-3.4.1.js', 'defer'); ?>
 <?php
@@ -65,7 +66,7 @@ if ($MARKDOWN) :
 <?php
 endif;
 ?>
-		<?php $this->_scriptTag('js/purify-3.3.2.js', 'defer'); ?>
+		<?php $this->_scriptTag('js/purify-3.4.1.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/legacy.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
 		<!-- icon -->

+ 3 - 2
tpl/bootstrap5.php

@@ -25,6 +25,7 @@ if ($SYNTAXHIGHLIGHTING) :
 endif;
 ?>
 		<noscript><link type="text/css" rel="stylesheet" href="css/noscript.css" /></noscript>
+		<?php $this->_linkTag('js/zlib-1.3.2.js'); ?>
 		<?php $this->_scriptTag('js/jquery-3.7.1.js', 'defer'); ?>
 <?php
 if ($QRCODE) :
@@ -33,7 +34,7 @@ if ($QRCODE) :
 <?php
 endif;
 ?>
-		<?php $this->_scriptTag('js/zlib-1.3.1-2.js', 'defer'); ?>
+		<?php $this->_scriptTag('js/zlib.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/base-x-5.0.1.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/bootstrap-5.3.8.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/dark-mode-switch.js', 'defer'); ?>
@@ -49,7 +50,7 @@ if ($MARKDOWN) :
 <?php
 endif;
 ?>
-		<?php $this->_scriptTag('js/purify-3.3.2.js', 'defer'); ?>
+		<?php $this->_scriptTag('js/purify-3.4.1.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/legacy.js', 'defer'); ?>
 		<?php $this->_scriptTag('js/privatebin.js', 'defer'); ?>
 		<!-- icon -->

+ 1 - 1
tst/Bootstrap.php

@@ -341,7 +341,7 @@ class Helper
      */
     public static function updateSubresourceIntegrity(): void
     {
-        foreach (new GlobIterator(PATH . 'js' . DIRECTORY_SEPARATOR . '*.js') as $file) {
+        foreach (new GlobIterator(PATH . 'js' . DIRECTORY_SEPARATOR . '*.*js') as $file) {
             if ($file->getBasename() === 'common.js' || $file->getBasename() === 'eslint.config.js') {
                 continue; // ignore JS unit test bootstrap
             }

+ 8 - 8
vendor/composer/installed.php

@@ -3,7 +3,7 @@
         'name' => 'privatebin/privatebin',
         'pretty_version' => 'dev-master',
         'version' => 'dev-master',
-        'reference' => '8eb39b4ffa8daed3d8ff0279c9870ee5b6b0bd95',
+        'reference' => '67baf8cca4b7aa1bc57e631b47ab561695c8ce2b',
         'type' => 'project',
         'install_path' => __DIR__ . '/../../',
         'aliases' => array(),
@@ -20,9 +20,9 @@
             'dev_requirement' => false,
         ),
         'mlocati/ip-lib' => array(
-            'pretty_version' => '1.21.0',
-            'version' => '1.21.0.0',
-            'reference' => 'b5d38cdcbfc1516604d821a1f3f4a1638f327267',
+            'pretty_version' => '1.22.0',
+            'version' => '1.22.0.0',
+            'reference' => '4e40ffd3bf9989db19403d89c4d8be44b87b8a91',
             'type' => 'library',
             'install_path' => __DIR__ . '/../mlocati/ip-lib',
             'aliases' => array(),
@@ -31,16 +31,16 @@
         'privatebin/privatebin' => array(
             'pretty_version' => 'dev-master',
             'version' => 'dev-master',
-            'reference' => '8eb39b4ffa8daed3d8ff0279c9870ee5b6b0bd95',
+            'reference' => '67baf8cca4b7aa1bc57e631b47ab561695c8ce2b',
             'type' => 'project',
             'install_path' => __DIR__ . '/../../',
             'aliases' => array(),
             'dev_requirement' => false,
         ),
         'symfony/polyfill-php80' => array(
-            'pretty_version' => 'v1.31.0',
-            'version' => '1.31.0.0',
-            'reference' => '60328e362d4c2c802a54fcbf04f9d3fb892b4cf8',
+            'pretty_version' => 'v1.34.0',
+            'version' => '1.34.0.0',
+            'reference' => 'dfb55726c3a76ea3b6459fcfda1ec2d80a682411',
             'type' => 'library',
             'install_path' => __DIR__ . '/../symfony/polyfill-php80',
             'aliases' => array(),

+ 3 - 1
vendor/mlocati/ip-lib/src/Address/AddressInterface.php

@@ -63,6 +63,8 @@ interface AddressInterface
      * Get the type of the IP address.
      *
      * @return int One of the \IPLib\Address\Type::T_... constants
+     *
+     * @phpstan-return \IPLib\Address\Type::T_IPv4|\IPLib\Address\Type::T_IPv6
      */
     public function getAddressType();
 
@@ -110,7 +112,7 @@ interface AddressInterface
     /**
      * Get the address at a certain distance from this address.
      *
-     * @param int|numeric-string $n the distance of the address (can be negative)
+     * @param int|numeric-string|mixed $n the distance of the address (can be negative)
      *
      * @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
      *

+ 18 - 7
vendor/mlocati/ip-lib/src/Address/IPv4.php

@@ -11,6 +11,8 @@ use IPLib\Service\NumberInChunks;
 
 /**
  * An IPv4 address.
+ *
+ * @phpstan-consistent-constructor
  */
 class IPv4 implements AddressInterface
 {
@@ -40,14 +42,14 @@ class IPv4 implements AddressInterface
     /**
      * A string representation of this address than can be used when comparing addresses and ranges.
      *
-     * @var string
+     * @var string|null
      */
     protected $comparableString;
 
     /**
      * An array containing RFC designated address ranges.
      *
-     * @var array|null
+     * @var \IPLib\Address\AssignedRange[]|null
      */
     private static $reservedRanges;
 
@@ -181,7 +183,7 @@ class IPv4 implements AddressInterface
     /**
      * Parse an array of bytes and returns an IPv4 instance if the array is valid, or null otherwise.
      *
-     * @param int[]|array $bytes
+     * @param array<int|mixed> $bytes
      *
      * @return static|null
      */
@@ -367,10 +369,14 @@ class IPv4 implements AddressInterface
                 $exceptions = array();
                 if (isset($data[1])) {
                     foreach ($data[1] as $exceptionRange => $exceptionType) {
-                        $exceptions[] = new AssignedRange(Subnet::parseString($exceptionRange), $exceptionType);
+                        $subnet = Subnet::parseString($exceptionRange);
+                        /** @var Subnet $subnet */
+                        $exceptions[] = new AssignedRange($subnet, $exceptionType);
                     }
                 }
-                $reservedRanges[] = new AssignedRange(Subnet::parseString($range), $data[0], $exceptions);
+                $subnet = Subnet::parseString($range);
+                /** @var Subnet $subnet */
+                $reservedRanges[] = new AssignedRange($subnet, $data[0], $exceptions);
             }
             self::$reservedRanges = $reservedRanges;
         }
@@ -407,8 +413,10 @@ class IPv4 implements AddressInterface
     public function toIPv6()
     {
         $myBytes = $this->getBytes();
+        $ipv6 = IPv6::parseString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::');
+        /** @var IPv6 $ipv6 */
 
-        return IPv6::parseString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::');
+        return $ipv6;
     }
 
     /**
@@ -420,7 +428,10 @@ class IPv4 implements AddressInterface
      */
     public function toIPv6IPv4Mapped()
     {
-        return IPv6::fromBytes(array_merge(array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff), $this->getBytes()));
+        $ipv6 = IPv6::fromBytes(array_merge(array(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff), $this->getBytes()));
+        /** @var IPv6 $ipv6 */
+
+        return $ipv6;
     }
 
     /**

+ 26 - 11
vendor/mlocati/ip-lib/src/Address/IPv6.php

@@ -11,6 +11,8 @@ use IPLib\Service\NumberInChunks;
 
 /**
  * An IPv6 address.
+ *
+ * @phpstan-consistent-constructor
  */
 class IPv6 implements AddressInterface
 {
@@ -56,7 +58,7 @@ class IPv6 implements AddressInterface
     /**
      * An array containing RFC designated address ranges.
      *
-     * @var array|null
+     * @var \IPLib\Address\AssignedRange[]|null
      */
     private static $reservedRanges;
 
@@ -144,7 +146,7 @@ class IPv6 implements AddressInterface
             }
         }
         $result = null;
-        if (is_string($address) && strpos($address, ':') !== false && strpos($address, ':::') === false) {
+        if (strpos($address, ':') !== false && strpos($address, ':::') === false) {
             if ($flags & ParseStringFlag::MAY_INCLUDE_PORT && $address[0] === '[' && preg_match('/^\[(.+)]:\d+$/', $address, $matches)) {
                 $address = $matches[1];
             }
@@ -212,7 +214,7 @@ class IPv6 implements AddressInterface
     /**
      * Parse an array of bytes and returns an IPv6 instance if the array is valid, or null otherwise.
      *
-     * @param int[]|array $bytes
+     * @param array<int|mixed> $bytes
      *
      * @return static|null
      */
@@ -244,7 +246,7 @@ class IPv6 implements AddressInterface
     /**
      * Parse an array of words and returns an IPv6 instance if the array is valid, or null otherwise.
      *
-     * @param int[]|array $words
+     * @param array<int|mixed> $words
      *
      * @return static|null
      */
@@ -353,7 +355,7 @@ class IPv6 implements AddressInterface
         if ($this->words === null) {
             $this->words = array_map(
                 function ($chunk) {
-                    return hexdec($chunk);
+                    return (int) hexdec($chunk);
                 },
                 explode(':', $this->longAddress)
             );
@@ -441,10 +443,14 @@ class IPv6 implements AddressInterface
                 $exceptions = array();
                 if (isset($data[1])) {
                     foreach ($data[1] as $exceptionRange => $exceptionType) {
-                        $exceptions[] = new AssignedRange(Subnet::parseString($exceptionRange), $exceptionType);
+                        $subnet = Subnet::parseString($exceptionRange);
+                        /** @var Subnet $subnet */
+                        $exceptions[] = new AssignedRange($subnet, $exceptionType);
                     }
                 }
-                $reservedRanges[] = new AssignedRange(Subnet::parseString($range), $data[0], $exceptions);
+                $subnet = Subnet::parseString($range);
+                /** @var Subnet $subnet */
+                $reservedRanges[] = new AssignedRange($subnet, $data[0], $exceptions);
             }
             self::$reservedRanges = $reservedRanges;
         }
@@ -517,11 +523,17 @@ class IPv6 implements AddressInterface
     {
         $myBytes = $this->getBytes();
         $ipv6Bytes = array_merge(array_slice($myBytes, 0, 12), array(0xff, 0xff, 0xff, 0xff));
-        $ipv6String = static::fromBytes($ipv6Bytes)->toString($ipV6Long);
+        $ipv6 = static::fromBytes($ipv6Bytes);
+        /** @var IPv6 $ipv6 */
+        $ipv6String = $ipv6->toString($ipV6Long);
         $ipv4Bytes = array_slice($myBytes, 12, 4);
-        $ipv4String = IPv4::fromBytes($ipv4Bytes)->toString($ipV4Long);
+        $ipv4 = IPv4::fromBytes($ipv4Bytes);
+        /** @var IPv4 $ipv4 */
+        $ipv4String = $ipv4->toString($ipV4Long);
+        $result = preg_replace('/((ffff:ffff)|(\d+(\.\d+){3}))$/i', $ipv4String, $ipv6String);
+        /** @var string $result */
 
-        return preg_replace('/((ffff:ffff)|(\d+(\.\d+){3}))$/i', $ipv4String, $ipv6String);
+        return $result;
     }
 
     /**
@@ -627,8 +639,11 @@ class IPv6 implements AddressInterface
             $paddedBits = substr($paddedBits, $absBits) . $pad;
         }
         $bytes = array_map('bindec', str_split($paddedBits, 16));
+        /** @var int[] $bytes */
+        $result = static::fromWords($bytes);
+        /** @var IPv6 $result */
 
-        return static::fromWords($bytes);
+        return $result;
     }
 
     /**

+ 2 - 2
vendor/mlocati/ip-lib/src/Address/Type.php

@@ -24,7 +24,7 @@ class Type
     /**
      * Get the name of a type.
      *
-     * @param int $type
+     * @param int|mixed $type
      *
      * @return string
      *
@@ -38,7 +38,7 @@ class Type
             case static::T_IPv6:
                 return 'IP v6';
             default:
-                return sprintf('Unknown type (%s)', $type);
+                return $type === null ? 'Unknown type' : sprintf('Unknown type (%s)', print_r($type, true));
         }
     }
 }

+ 69 - 25
vendor/mlocati/ip-lib/src/Factory.php

@@ -48,35 +48,33 @@ class Factory
      */
     public static function parseAddressString($address, $flags = 0)
     {
-        $result = null;
-        if ($result === null) {
-            $result = Address\IPv4::parseString($address, $flags);
+        if (($result = Address\IPv4::parseString($address, $flags)) !== null) {
+            return $result;
         }
-        if ($result === null) {
-            $result = Address\IPv6::parseString($address, $flags);
+        if (($result = Address\IPv6::parseString($address, $flags)) !== null) {
+            return $result;
         }
 
-        return $result;
+        return null;
     }
 
     /**
      * Convert a byte array to an address instance.
      *
-     * @param int[]|array $bytes
+     * @param array<int|mixed> $bytes
      *
      * @return \IPLib\Address\AddressInterface|null
      */
     public static function addressFromBytes(array $bytes)
     {
-        $result = null;
-        if ($result === null) {
-            $result = Address\IPv4::fromBytes($bytes);
+        if (($result = Address\IPv4::fromBytes($bytes)) !== null) {
+            return $result;
         }
-        if ($result === null) {
-            $result = Address\IPv6::fromBytes($bytes);
+        if (($result = Address\IPv6::fromBytes($bytes)) !== null) {
+            return $result;
         }
 
-        return $result;
+        return null;
     }
 
     /**
@@ -100,7 +98,7 @@ class Factory
     /**
      * Parse an IP range string.
      *
-     * @param string $range
+     * @param string|mixed $range
      * @param int $flags A combination or zero or more flags
      *
      * @return \IPLib\Range\RangeInterface|null
@@ -110,10 +108,7 @@ class Factory
      */
     public static function parseRangeString($range, $flags = 0)
     {
-        $result = null;
-        if ($result === null) {
-            $result = Range\Subnet::parseString($range, $flags);
-        }
+        $result = Range\Subnet::parseString($range, $flags);
         if ($result === null) {
             $result = Range\Pattern::parseString($range, $flags);
         }
@@ -133,7 +128,7 @@ class Factory
      * @param string|\IPLib\Address\AddressInterface|mixed $to
      * @param bool $supportNonDecimalIPv4
      *
-     * @return \IPLib\Address\AddressInterface|null
+     * @return \IPLib\Range\RangeInterface|null
      *
      * @see \IPLib\Factory::getRangeFromBoundaries()
      * @since 1.2.0
@@ -163,6 +158,53 @@ class Factory
         return $from === false || $to === false ? null : static::rangeFromBoundaryAddresses($from, $to);
     }
 
+    /**
+     * Calculate the minimal range that contains all the specified addresses.
+     *
+     * @param array<non-empty-string|\IPLib\Address\AddressInterface|mixed> $addresses
+     * @param int $flags
+     *
+     * @return \IPLib\Range\RangeInterface|null Returns NULL if $addresses is empty, if it contains invalid addresses, or if the addresses aren't compatible (for example, both IPv4 and IPv6 addresses)
+     *
+     * @since 1.22.0
+     */
+    public static function getRangeFromAddresses(array $addresses, $flags = 0)
+    {
+        $min = null;
+        $max = null;
+        $numberOfBits = null;
+        foreach ($addresses as $address) {
+            if (!$address instanceof AddressInterface) {
+                $address = Factory::parseAddressString($address, $flags);
+                if ($address === null) {
+                    return null;
+                }
+            }
+            if ($numberOfBits === null) {
+                $min = $address;
+                $max = $address;
+                $numberOfBits = $address->getNumberOfBits();
+            } elseif ($numberOfBits !== $address->getNumberOfBits()) {
+                return null;
+            } else {
+                /** @var AddressInterface $min */
+                /** @var AddressInterface $max */
+                $comparable = $address->getComparableString();
+                if ($min->getComparableString() > $comparable) {
+                    $min = $address;
+                }
+                if ($max->getComparableString() < $comparable) {
+                    $max = $address;
+                }
+            }
+        }
+        if ($numberOfBits === null) {
+            return null;
+        }
+
+        return static::rangeFromBoundaryAddresses($min, $max);
+    }
+
     /**
      * @deprecated since 1.17.0: use the getRangesFromBoundaries() method instead.
      * For upgrading:
@@ -185,8 +227,8 @@ class Factory
     /**
      * Create a list of Range instances that exactly describes all the addresses between the two provided addresses.
      *
-     * @param string|\IPLib\Address\AddressInterface $from
-     * @param string|\IPLib\Address\AddressInterface $to
+     * @param string|\IPLib\Address\AddressInterface|mixed $from
+     * @param string|\IPLib\Address\AddressInterface|mixed $to
      * @param int $flags A combination or zero or more flags
      *
      * @return \IPLib\Range\Subnet[]|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
@@ -202,6 +244,7 @@ class Factory
         }
         if ($from === null || $to === null) {
             $address = $from ? $from : $to;
+            /** @var AddressInterface $address */
 
             return array(new Subnet($address, $address, $address->getNumberOfBits()));
         }
@@ -265,11 +308,11 @@ class Factory
     }
 
     /**
-     * @param string|\IPLib\Address\AddressInterface $from
-     * @param string|\IPLib\Address\AddressInterface $to
+     * @param string|\IPLib\Address\AddressInterface|mixed $from
+     * @param string|\IPLib\Address\AddressInterface|mixed $to
      * @param int $flags
      *
-     * @return \IPLib\Address\AddressInterface[]|null[]|false[]
+     * @return array{\IPLib\Address\AddressInterface|false|null, \IPLib\Address\AddressInterface|false|null}
      */
     private static function parseBoundaries($from, $to, $flags = 0)
     {
@@ -277,7 +320,7 @@ class Factory
         foreach (array('from', 'to') as $param) {
             $value = $$param;
             if (!($value instanceof AddressInterface)) {
-                $value = (string) $value;
+                $value = is_object($value) && method_exists($value, '__toString') || is_scalar($value) ? (string) $value : '';
                 if ($value === '') {
                     $value = null;
                 } else {
@@ -289,6 +332,7 @@ class Factory
             }
             $result[] = $value;
         }
+        /** @var array{\IPLib\Address\AddressInterface|false|null, \IPLib\Address\AddressInterface|false|null} $result */
         if ($result[0] && $result[1] && strcmp($result[0]->getComparableString(), $result[1]->getComparableString()) > 0) {
             $result = array($result[1], $result[0]);
         }

+ 21 - 13
vendor/mlocati/ip-lib/src/Range/AbstractRange.php

@@ -22,10 +22,18 @@ abstract class AbstractRange implements RangeInterface
      */
     public function getRangeType()
     {
+        /** @var \IPLib\Range\Pattern|\IPLib\Range\Subnet $this */
+        // @phpstan-ignore varTag.nativeType
         if ($this->rangeType === null) {
             $addressType = $this->getAddressType();
             if ($addressType === AddressType::T_IPv6 && Subnet::get6to4()->containsRange($this)) {
-                $this->rangeType = Factory::getRangeFromBoundaries($this->fromAddress->toIPv4(), $this->toAddress->toIPv4())->getRangeType();
+                $fromAddress = $this->fromAddress;
+                /** @var IPv6 $fromAddress */
+                $toAddress = $this->toAddress;
+                /** @var IPv6 $toAddress */
+                $range = Factory::getRangeFromBoundaries($fromAddress->toIPv4(), $toAddress->toIPv4());
+                /** @var RangeInterface $range */
+                $this->rangeType = $range->getRangeType();
             } else {
                 switch ($addressType) {
                     case AddressType::T_IPv4:
@@ -36,8 +44,6 @@ abstract class AbstractRange implements RangeInterface
                         $defaultType = IPv6::getDefaultReservedRangeType();
                         $reservedRanges = IPv6::getReservedRanges();
                         break;
-                    default:
-                        throw new \Exception('@todo'); // @codeCoverageIgnore
                 }
                 $rangeType = null;
                 foreach ($reservedRanges as $reservedRange) {
@@ -62,23 +68,20 @@ abstract class AbstractRange implements RangeInterface
     {
         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;
         }
         if ($positive) {
             $start = Factory::parseAddressString($this->getComparableStartString());
+            /** @var \IPLib\Address\AddressInterface $start */
             $address = $start->getAddressAtOffset($n);
         } else {
             $end = Factory::parseAddressString($this->getComparableEndString());
+            /** @var \IPLib\Address\AddressInterface $end */
+            $nPlus1 = is_int($n) ? $n + 1 : BinaryMath::getInstance()->add1ToIntegerString($n);
             $address = $end->getAddressAtOffset($nPlus1);
         }
 
@@ -156,15 +159,20 @@ abstract class AbstractRange implements RangeInterface
         if ($networkPrefix > $maxPrefix) {
             throw new OutOfBoundsException("The value of the \$networkPrefix parameter can't be larger than the maximum network prefix of the range ({$maxPrefix})");
         }
-        if ($startIp instanceof IPv4) {
-            $one = IPv4::fromBytes(array(0, 0, 0, 1));
-        } elseif ($startIp instanceof IPv6) {
-            $one = IPv6::fromBytes(array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
+        switch ($startIp->getAddressType()) {
+            case AddressType::T_IPv4:
+                $one = IPv4::fromBytes(array(0, 0, 0, 1));
+                break;
+            case AddressType::T_IPv6:
+                $one = IPv6::fromBytes(array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1));
+                break;
         }
+        /** @var \IPLib\Address\AddressInterface $one */
         $delta = $one->shift($networkPrefix - $maxPrefix);
         $result = array();
         while (true) {
             $range = Subnet::parseString("{$startIp}/{$networkPrefix}");
+            /** @var Subnet $range */
             if (!$forceSubnet && $this instanceof Pattern) {
                 $range = $range->asPattern() ?: $range;
             }

+ 17 - 2
vendor/mlocati/ip-lib/src/Range/Pattern.php

@@ -14,6 +14,8 @@ use IPLib\Service\BinaryMath;
  *
  * @example 127.0.*.*
  * @example ::/8
+ *
+ * @phpstan-consistent-constructor
  */
 class Pattern extends AbstractRange
 {
@@ -106,10 +108,20 @@ class Pattern extends AbstractRange
             return null;
         }
         if ($range === '*.*.*.*') {
-            return new static(IPv4::parseString('0.0.0.0'), IPv4::parseString('255.255.255.255'), 4);
+            $fromAddress = IPv4::parseString('0.0.0.0');
+            /** @var \IPLib\Address\IPv4 $fromAddress */
+            $toAddress = IPv4::parseString('255.255.255.255');
+            /** @var \IPLib\Address\IPv4 $toAddress */
+
+            return new static($fromAddress, $toAddress, 4);
         }
         if ($range === '*:*:*:*:*:*:*:*') {
-            return new static(IPv6::parseString('::'), IPv6::parseString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 8);
+            $fromAddress = IPv6::parseString('::');
+            /** @var \IPLib\Address\IPv6 $fromAddress */
+            $toAddress = IPv6::parseString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff');
+            /** @var \IPLib\Address\IPv6 $toAddress */
+
+            return new static($fromAddress, $toAddress, 8);
         }
         $matches = null;
         if (strpos($range, '.') !== false && preg_match('/^[^*]+((?:\.\*)+)$/', $range, $matches)) {
@@ -128,6 +140,7 @@ class Pattern extends AbstractRange
             $fixedBytes = array_slice($fromAddress->getBytes(), 0, -$asterisksCount);
             $otherBytes = array_fill(0, $asterisksCount, 255);
             $toAddress = IPv4::fromBytes(array_merge($fixedBytes, $otherBytes));
+            /** @var \IPLib\Address\IPv4 $toAddress */
 
             return new static($fromAddress, $toAddress, $asterisksCount);
         }
@@ -140,6 +153,7 @@ class Pattern extends AbstractRange
             $fixedWords = array_slice($fromAddress->getWords(), 0, -$asterisksCount);
             $otherWords = array_fill(0, $asterisksCount, 0xffff);
             $toAddress = IPv6::fromWords(array_merge($fixedWords, $otherWords));
+            /** @var \IPLib\Address\IPv6 $toAddress */
 
             return new static($fromAddress, $toAddress, $asterisksCount);
         }
@@ -177,6 +191,7 @@ class Pattern extends AbstractRange
                     $bytes = array_slice($bytes, 0, -$this->asterisksCount * 2);
                     $bytes = array_pad($bytes, 16, 1);
                     $address = IPv6::fromBytes($bytes);
+                    /** @var IPv6 $address */
                     $before = substr($address->toString(false), 0, -strlen(':101') * $this->asterisksCount);
                     $result = $before . str_repeat(':*', $this->asterisksCount);
                 }

+ 4 - 2
vendor/mlocati/ip-lib/src/Range/RangeInterface.php

@@ -31,13 +31,15 @@ interface RangeInterface
      * Get the type of the IP addresses contained in this range.
      *
      * @return int One of the \IPLib\Address\Type::T_... constants
+     *
+     * @phpstan-return \IPLib\Address\Type::T_IPv4|\IPLib\Address\Type::T_IPv6
      */
     public function getAddressType();
 
     /**
      * Get the type of range of the IP address.
      *
-     * @return int One of the \IPLib\Range\Type::T_... constants
+     * @return int|null One of the \IPLib\Range\Type::T_... constants, or null if this range crosses multiple range types
      *
      * @since 1.5.0
      */
@@ -46,7 +48,7 @@ interface RangeInterface
     /**
      * Get the address at a certain offset of this range.
      *
-     * @param int|numeric-string $n the offset of the address (support negative offset)
+     * @param int|numeric-string|mixed $n the offset of the address (support negative offset)
      *
      * @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
      *

+ 2 - 0
vendor/mlocati/ip-lib/src/Range/Single.php

@@ -13,6 +13,8 @@ use IPLib\ParseStringFlag;
  *
  * @example 127.0.0.1
  * @example ::1
+ *
+ * @phpstan-consistent-constructor
  */
 class Single extends AbstractRange
 {

+ 14 - 9
vendor/mlocati/ip-lib/src/Range/Subnet.php

@@ -14,6 +14,8 @@ use IPLib\Service\BinaryMath;
  *
  * @example 127.0.0.1/32
  * @example ::/8
+ *
+ * @phpstan-consistent-constructor
  */
 class Subnet extends AbstractRange
 {
@@ -146,15 +148,15 @@ class Subnet extends AbstractRange
         $startSameBits = $networkPrefix % 8;
         if ($startSameBits !== 0) {
             $varyingByte = $addressBytes[$numSameBytes];
-            $differentBytesStart[0] = $varyingByte & bindec(str_pad(str_repeat('1', $startSameBits), 8, '0', STR_PAD_RIGHT));
-            $differentBytesEnd[0] = $differentBytesStart[0] + bindec(str_repeat('1', 8 - $startSameBits));
+            $differentBytesStart[0] = $varyingByte & (int) bindec(str_pad(str_repeat('1', $startSameBits), 8, '0', STR_PAD_RIGHT));
+            $differentBytesEnd[0] = $differentBytesStart[0] + (int) bindec(str_repeat('1', 8 - $startSameBits));
         }
+        $fromAddress = Factory::addressFromBytes(array_merge($sameBytes, $differentBytesStart));
+        /** @var \IPLib\Address\AddressInterface $fromAddress */
+        $toAddress = Factory::addressFromBytes(array_merge($sameBytes, $differentBytesEnd));
+        /** @var \IPLib\Address\AddressInterface $toAddress */
 
-        return new static(
-            Factory::addressFromBytes(array_merge($sameBytes, $differentBytesStart)),
-            Factory::addressFromBytes(array_merge($sameBytes, $differentBytesEnd)),
-            $networkPrefix
-        );
+        return new static($fromAddress, $toAddress, $networkPrefix);
     }
 
     /**
@@ -255,7 +257,9 @@ class Subnet extends AbstractRange
     public static function get6to4()
     {
         if (self::$sixToFour === null) {
-            self::$sixToFour = self::parseString('2002::/16');
+            $subnet = self::parseString('2002::/16');
+            /** @var Subnet $subnet */
+            self::$sixToFour = $subnet;
         }
 
         return self::$sixToFour;
@@ -327,10 +331,11 @@ class Subnet extends AbstractRange
         $result = array();
         $unitsToRemove = $maxUnits - $prefixUnits;
         $initialPointer = preg_replace("/^(({$rxUnit})\.){{$unitsToRemove}}/", '', $this->getStartAddress()->getReverseDNSLookupName());
+        /** @var string $initialPointer */
         $chunks = explode('.', $initialPointer, 2);
         for ($index = 0; $index < $numVariants; $index++) {
             if ($index !== 0) {
-                $chunks[0] = $isHex ? dechex(1 + hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]);
+                $chunks[0] = $isHex ? dechex(1 + (int) hexdec($chunks[0])) : (string) (1 + (int) $chunks[0]);
             }
             $result[] = implode('.', $chunks);
         }

+ 2 - 2
vendor/mlocati/ip-lib/src/Range/Type.php

@@ -110,7 +110,7 @@ class Type
     /**
      * Get the name of a type.
      *
-     * @param int $type
+     * @param int|mixed $type
      *
      * @return string
      */
@@ -146,7 +146,7 @@ class Type
             case static::T_CGNAT:
                 return 'Carrier-grade NAT';
             default:
-                return $type === null ? 'Unknown type' : sprintf('Unknown type (%s)', $type);
+                return $type === null ? 'Unknown type' : sprintf('Unknown type (%s)', print_r($type, true));
         }
     }
 }

+ 22 - 8
vendor/mlocati/ip-lib/src/Service/BinaryMath.php

@@ -9,6 +9,9 @@ namespace IPLib\Service;
  */
 class BinaryMath
 {
+    /**
+     * @var \IPLib\Service\BinaryMath|null
+     */
     private static $instance;
 
     /**
@@ -119,7 +122,7 @@ class BinaryMath
      *
      * @param int $exponent The non-negative exponent
      *
-     * @return int|string
+     * @return int|numeric-string
      */
     public function pow2string($exponent)
     {
@@ -138,14 +141,16 @@ class BinaryMath
                 $digits[] = $carry;
             }
         }
+        $result = implode('', array_reverse($digits));
+        /** @var numeric-string $result */
 
-        return implode('', array_reverse($digits));
+        return $result;
     }
 
     /**
      * @param numeric-string|mixed $value
      *
-     * @return string empty string if $value is not a valid numeric string
+     * @return numeric-string|'' empty string if $value is not a valid numeric string
      */
     public function normalizeIntegerString($value)
     {
@@ -160,14 +165,19 @@ class BinaryMath
         if (!preg_match('/^0*([0-9]+)$/', $value, $matches)) {
             return '';
         }
+        $numericString = $matches[1];
+        if ($sign === '-' && $numericString !== '0') {
+            $numericString = '-' . $numericString;
+        }
+        /** @var numeric-string $numericString */
 
-        return ($sign === '-' && $matches[1] !== '0' ? $sign : '') . $matches[1];
+        return $numericString;
     }
 
     /**
      * @param numeric-string $value a string that has been normalized with normalizeIntegerString()
      *
-     * @return string
+     * @return numeric-string
      */
     public function add1ToIntegerString($value)
     {
@@ -189,8 +199,10 @@ class BinaryMath
             if ($imploded[0] === '0') {
                 $imploded = substr($imploded, 1);
             }
+            $result = '-' . $imploded;
+            /** @var numeric-string $result */
 
-            return '-' . $imploded;
+            return $result; // @phpstan-ignore varTag.nativeType
         }
         $digits = str_split($value);
         $carry = 1;
@@ -205,8 +217,10 @@ class BinaryMath
                 array_unshift($digits, (string) $carry);
             }
         }
+        $result = implode('', $digits);
+        /** @var numeric-string $result */
 
-        return implode('', $digits);
+        return $result;
     }
 
     /**
@@ -215,7 +229,7 @@ class BinaryMath
      * @param string $num1
      * @param string $num2
      *
-     * @return string[],int[] The first array element is $num1 (padded), the first array element is $num2 (padded), the third array element is the number of bits
+     * @return array{string, string, int} The first array element is $num1 (padded), the first array element is $num2 (padded), the third array element is the number of bits
      */
     private function toSameLength($num1, $num2)
     {

+ 3 - 2
vendor/mlocati/ip-lib/src/Service/NumberInChunks.php

@@ -88,7 +88,8 @@ class NumberInChunks
         $negative = $int < 0;
         if ($negative) {
             $positiveInt = -$int;
-            if (is_float($positiveInt)) { // -PHP_INT_MIN is bigger than PHP_INT_MAX
+            /** @var int|float $positiveInt may be float because -PHP_INT_MIN is bigger than PHP_INT_MAX */
+            if (is_float($positiveInt)) {
                 return self::fromNumericString((string) $int, $chunkSize);
             }
             $int = $positiveInt;
@@ -197,7 +198,7 @@ class NumberInChunks
      * @param int[] $subtrahend
      * @param int $chunkSize
      *
-     * @return array
+     * @return array{bool, int[]}
      */
     private static function substractChunks(array $minuend, array $subtrahend, $chunkSize)
     {

+ 9 - 2
vendor/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php

@@ -80,6 +80,8 @@ class RangesFromBoundaryCalculator
      * Set the number of bits used to represent addresses (32 for IPv4, 128 for IPv6).
      *
      * @param int $numBits
+     *
+     * @return void
      */
     private function setNumBits($numBits)
     {
@@ -102,6 +104,8 @@ class RangesFromBoundaryCalculator
      * @param string $end the end address (represented in reduced bit form)
      * @param int $position the number of bits in the mask we are comparing at this cycle
      * @param \IPLib\Range\Subnet[] $result found ranges will be added to this variable
+     *
+     * @return void
      */
     private function calculate($start, $end, $position, array &$result)
     {
@@ -110,6 +114,7 @@ class RangesFromBoundaryCalculator
 
             return;
         }
+        $startMasked = '';
         for ($index = $position - 1; $index >= 0; $index--) {
             $startMasked = $this->math->andX($start, $this->masks[$index]);
             $endMasked = $this->math->andX($end, $this->masks[$index]);
@@ -140,10 +145,12 @@ class RangesFromBoundaryCalculator
         $bits = str_pad($bits, $this->numBits, '0', STR_PAD_LEFT);
         $bytes = array();
         foreach (explode("\n", trim(chunk_split($bits, 8, "\n"))) as $byteBits) {
-            $bytes[] = bindec($byteBits);
+            $bytes[] = (int) bindec($byteBits);
         }
+        $result = Factory::addressFromBytes($bytes);
+        /** @var AddressInterface $result */
 
-        return Factory::addressFromBytes($bytes);
+        return $result;
     }
 
     /**

+ 4 - 2
vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php

@@ -67,6 +67,7 @@ class UnsignedIntegerMath
             $value = str_pad($value, $valueLength + 8 - $remainderBits, '0', STR_PAD_LEFT);
         }
         $bytes = array_map('bindec', str_split($value, 8));
+        /** @var int[] $bytes */
 
         return array_pad($bytes, -$numBytes, 0);
     }
@@ -86,14 +87,14 @@ class UnsignedIntegerMath
             '',
             array_map(
                 function ($octalDigit) {
-                    return str_pad(decbin(octdec($octalDigit)), 3, '0', STR_PAD_LEFT);
+                    return str_pad(decbin((int) octdec($octalDigit)), 3, '0', STR_PAD_LEFT);
                 },
                 str_split($value, 1)
             )
         );
         $bits = ltrim($bits, '0');
 
-        return $bits === '' ? array_fill(0, $numBytes, 0) : static::getBytesFromBits($bits, $numBytes);
+        return $bits === '' ? array_fill(0, $numBytes, 0) : self::getBytesFromBits($bits, $numBytes);
     }
 
     /**
@@ -165,6 +166,7 @@ class UnsignedIntegerMath
         }
         $value = str_pad($value, $valueLength + $valueLength % 2, '0', STR_PAD_LEFT);
         $bytes = array_map('hexdec', str_split($value, 2));
+        /** @var int[] $bytes */
 
         return array_pad($bytes, -$numBytes, 0);
     }

+ 1 - 1
vendor/symfony/polyfill-php80/Php80.php

@@ -60,7 +60,7 @@ final class Php80
     public static function get_resource_id($res): int
     {
         if (!\is_resource($res) && null === @get_resource_type($res)) {
-            throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
+            throw new \TypeError(\sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
         }
 
         return (int) $res;

+ 5 - 2
vendor/symfony/polyfill-php80/PhpToken.php

@@ -29,7 +29,7 @@ class PhpToken implements \Stringable
     public $text;
 
     /**
-     * @var int
+     * @var -1|positive-int
      */
     public $line;
 
@@ -38,6 +38,9 @@ class PhpToken implements \Stringable
      */
     public $pos;
 
+    /**
+     * @param -1|positive-int $line
+     */
     public function __construct(int $id, string $text, int $line = -1, int $position = -1)
     {
         $this->id = $id;
@@ -80,7 +83,7 @@ class PhpToken implements \Stringable
     }
 
     /**
-     * @return static[]
+     * @return list<static>
      */
     public static function tokenize(string $code, int $flags = 0): array
     {

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.