aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2026-09-18 07:32:53 +0000
committergithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2026-09-18 07:32:53 +0000
commit2043d7ee29a4b10a0fc294db9520973fc550e913 (patch)
tree7b79ff10ef84d48f0f773859b07999a84d425b01
parentmaintenance.sh: simpler script directory detection (diff)
downloadwireguard-config-2043d7ee29a4b10a0fc294db9520973fc550e913.tar.gz
wireguard-config-2043d7ee29a4b10a0fc294db9520973fc550e913.zip
bump dependencies
-rw-r--r--Gemfile.lock2
-rw-r--r--package-lock.json26
-rw-r--r--src/assets/js/bundle.js58
3 files changed, 64 insertions, 22 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index 2b5fe72..c4b6c29 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -12,7 +12,7 @@ GEM
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
- faraday (2.14.3)
+ faraday (2.14.4)
faraday-net_http (>= 2.0, < 3.5)
json
logger
diff --git a/package-lock.json b/package-lock.json
index 80350f4..6f3fe57 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -131,9 +131,9 @@
"license": "MIT"
},
"node_modules/brace-expansion": {
- "version": "1.1.18",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz",
- "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==",
+ "version": "1.1.21",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
+ "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -1034,9 +1034,9 @@
}
},
"node_modules/ip-address": {
- "version": "10.7.0",
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz",
- "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==",
+ "version": "10.7.2",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.2.tgz",
+ "integrity": "sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==",
"license": "MIT",
"engines": {
"node": ">= 12"
@@ -1077,12 +1077,12 @@
}
},
"node_modules/is-core-module": {
- "version": "2.16.2",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
- "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.17.0.tgz",
+ "integrity": "sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==",
"license": "MIT",
"dependencies": {
- "hasown": "^2.0.3"
+ "hasown": "^2.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -2057,9 +2057,9 @@
"license": "MIT"
},
"node_modules/which-typed-array": {
- "version": "1.1.22",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
- "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
+ "version": "1.1.23",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.23.tgz",
+ "integrity": "sha512-JMh8aK+1B/0bk/YNupICmH5MgCq6yNLKYQUfsZtSDLLCCmxUkHjUY+oOlIa90lO7lHN1woAfpenLdlKpXy9o+A==",
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
diff --git a/src/assets/js/bundle.js b/src/assets/js/bundle.js
index 8327238..5764765 100644
--- a/src/assets/js/bundle.js
+++ b/src/assets/js/bundle.js
@@ -52,8 +52,20 @@ function isInSubnet(address) {
* {@link isInSubnet} when classifying a single address — notably when the
* address came from untrusted input and the result backs a trust-boundary
* decision such as an SSRF allow/deny filter.
+ *
+ * An address of one family is never inside a network of the other, so an
+ * `Address4` against an `Address6` (or the reverse) is `false`. To compare
+ * across families, convert first: `Address6.fromAddress4()`, `to4()`, or
+ * `toAddress4Nat64()`.
*/
function isHostInSubnet(address) {
+ // mask() is a bit string of the family's width, and the leading bits of a
+ // 32-bit string can coincide with those of a 128-bit one (a00::1 and
+ // 10.0.0.0/8 both mask to 00001010), so the widths must agree before the
+ // strings are compared.
+ if (this.binaryZeroPad().length !== address.binaryZeroPad().length) {
+ return false;
+ }
return this.mask(address.subnetMask) === address.mask();
}
/**
@@ -205,7 +217,9 @@ class Address4 {
*/
this.isCorrect = isCorrect4;
/**
- * Returns true if the given address is in the subnet of the current address
+ * Returns true if the given address is in the subnet of the current address.
+ * An `Address6` is never in the subnet of an `Address4`; convert with
+ * `to4()` or `Address6.fromAddress4()` to compare across families.
* @returns {boolean}
*/
this.isInSubnet = common.isInSubnet;
@@ -215,6 +229,8 @@ class Address4 {
* when classifying a single address, so the answer doesn't change with the
* CIDR suffix the caller happened to write — notably when the address came
* from untrusted input and the result backs a trust-boundary decision.
+ * An `Address6` is never in the subnet of an `Address4`; convert with
+ * `to4()` or `Address6.fromAddress4()` to compare across families.
* @returns {boolean}
*/
this.isHostInSubnet = common.isHostInSubnet;
@@ -229,6 +245,13 @@ class Address4 {
}
address = address.replace(constants.RE_SUBNET_STRING, '');
}
+ // Four three-digit octets and three dots: the longest well-formed address
+ // is 15 characters. Longer input is rejected before parsing, as Address6
+ // does at its own limit.
+ const longest = constants.GROUPS * 4 - 1;
+ if (address.length > longest) {
+ throw new address_error_1.AddressError(`IPv4 addresses are at most ${longest} characters.`);
+ }
this.addressMinusSuffix = address;
this.parsedAddress = this.parse(address);
}
@@ -370,16 +393,20 @@ class Address4 {
return Address4.fromHex(integer.toString(16).padStart(8, '0'));
}
/**
- * Return an address from in-addr.arpa form
+ * Return an address from in-addr.arpa form: the four octets reversed, with
+ * or without the `.in-addr.arpa` suffix and root dot, in any case. Throws
+ * `AddressError` unless the reversed labels form a valid IPv4 address, so
+ * `fromArpa(x.reverseForm())` round-trips {@link reverseForm}.
* @param {string} arpaFormAddress - an 'in-addr.arpa' form ipv4 address
* @returns {Adress4}
* @example
- * var address = Address4.fromArpa(42.2.0.192.in-addr.arpa.)
+ * var address = Address4.fromArpa('42.2.0.192.in-addr.arpa.')
* address.correctForm(); // '192.0.2.42'
*/
static fromArpa(arpaFormAddress) {
- // remove ending ".in-addr.arpa." or just "."
- const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.$/, '');
+ // remove an ending ".in-addr.arpa", in any case and with or without the
+ // root dot, as Address6.fromArpa does for ".ip6.arpa"
+ const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.?$/i, '');
const address = leader.split('.').reverse().join('.');
return new Address4(address);
}
@@ -830,7 +857,9 @@ class Address6 {
this.zone = '';
// #region Attributes
/**
- * Returns true if the given address is in the subnet of the current address
+ * Returns true if the given address is in the subnet of the current address.
+ * An `Address4` is never in the subnet of an `Address6`; convert with
+ * `Address6.fromAddress4()` or `to4()` to compare across families.
* @returns {boolean}
*/
this.isInSubnet = common.isInSubnet;
@@ -840,6 +869,8 @@ class Address6 {
* when classifying a single address, so the answer doesn't change with the
* CIDR suffix the caller happened to write — notably when the address came
* from untrusted input and the result backs a trust-boundary decision.
+ * An `Address4` is never in the subnet of an `Address6`; convert with
+ * `Address6.fromAddress4()` or `to4()` to compare across families.
* @returns {boolean}
*/
this.isHostInSubnet = common.isHostInSubnet;
@@ -878,6 +909,16 @@ class Address6 {
this.zone = zone[0];
address = address.replace(constants6.RE_ZONE_STRING, '');
}
+ // The longest well-formed address is all but the last two groups written
+ // as four hex digits with their colons, then a 15-character dotted quad:
+ // 5 * (groups - 2) + 15, which is 45 for eight groups, the same line
+ // CPython's ipaddress module draws. Rejecting longer input here keeps the
+ // parse diagnostics, which wrap every offending character in a span,
+ // proportional to an address rather than to whatever was passed in.
+ const longest = this.groups * 5 + 5;
+ if (address.length > longest) {
+ throw new address_error_1.AddressError(`IPv6 addresses are at most ${longest} characters.`);
+ }
this.addressMinusSuffix = address;
this.parsedAddress = this.parse(this.addressMinusSuffix);
}
@@ -1089,8 +1130,9 @@ class Address6 {
* Address6.fromArpa('8.b.d.0.1.0.0.2.ip6.arpa.').networkForm(); // '2001:db8::/32'
*/
static fromArpa(arpaFormAddress) {
- // remove an ending ".ip6.arpa", with or without the root dot
- const nibbles = arpaFormAddress.replace(/(\.ip6\.arpa)?\.?$/, '');
+ // remove an ending ".ip6.arpa", in any case and with or without the root
+ // dot
+ const nibbles = arpaFormAddress.replace(/(\.ip6\.arpa)?\.?$/i, '');
if (!/^[0-9a-f](\.[0-9a-f]){0,31}$/i.test(nibbles)) {
throw new address_error_1.AddressError("Invalid 'ip6.arpa' form.");
}