tldts-tests 7.0.31 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/tldts-tests.js +107 -3
- package/dist/cjs/src/tldts-tests.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/es6/src/tldts-tests.js +107 -3
- package/dist/es6/src/tldts-tests.js.map +1 -1
- package/dist/es6/tsconfig.bundle.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/tldts-tests.ts +129 -3
package/src/tldts-tests.ts
CHANGED
|
@@ -147,6 +147,11 @@ export default function test(
|
|
|
147
147
|
'while',
|
|
148
148
|
'with',
|
|
149
149
|
'yield',
|
|
150
|
+
// Object.prototype-member labels (lowercase, so they survive hostname
|
|
151
|
+
// lowercasing): must be treated as ordinary labels, never resolve
|
|
152
|
+
// against the prototype chain during trie traversal.
|
|
153
|
+
'constructor',
|
|
154
|
+
'__proto__',
|
|
150
155
|
].forEach((keyword) => {
|
|
151
156
|
it(keyword, () => {
|
|
152
157
|
expect(tldts.getDomain(`https://${keyword}.com`)).to.equal(
|
|
@@ -305,6 +310,16 @@ export default function test(
|
|
|
305
310
|
});
|
|
306
311
|
});
|
|
307
312
|
|
|
313
|
+
// Labels ending with '_' (e.g. SPF / DNS-TXT records). Allowed by DNS (RFC 2181 §11)
|
|
314
|
+
// and WHATWG URL ('_' is not a forbidden host code point); only the RFC 1035 LDH
|
|
315
|
+
// "preferred syntax" forbids it, which tldts intentionally does not enforce.
|
|
316
|
+
it('should accept labels ending with an underscore', () => {
|
|
317
|
+
expect(tldts.getDomain('spf_.google.com')).to.equal('google.com'); // reported bug
|
|
318
|
+
expect(tldts.getHostname('spf_.google.com')).to.equal('spf_.google.com'); // full hostname preserved
|
|
319
|
+
expect(tldts.getDomain('_spf.google.com')).to.equal('google.com'); // leading '_' (reference case)
|
|
320
|
+
expect(tldts.getDomain('s_pf.google.com')).to.equal('google.com'); // middle '_' (reference case)
|
|
321
|
+
});
|
|
322
|
+
|
|
308
323
|
// @see https://github.com/oncletom/tld.js/issues/53
|
|
309
324
|
it('should correctly extract domain from paths including "@" in the path', () => {
|
|
310
325
|
const domain = tldts.getDomain(
|
|
@@ -653,9 +668,10 @@ export default function test(
|
|
|
653
668
|
it('should be consistent with parse method', () => {
|
|
654
669
|
const url = '___id___.c.mystat-in.net';
|
|
655
670
|
|
|
656
|
-
//
|
|
657
|
-
|
|
658
|
-
expect(tldts.
|
|
671
|
+
// Underscores (incl. trailing) are accepted — DNS allows any octet (RFC 2181 §11),
|
|
672
|
+
// WHATWG URL does not forbid '_'. parse() and getHostname() must agree.
|
|
673
|
+
expect(tldts.parse(url).hostname).to.equal(url);
|
|
674
|
+
expect(tldts.getHostname(url)).to.equal(url);
|
|
659
675
|
|
|
660
676
|
// Without validation
|
|
661
677
|
expect(tldts.parse(url, { validateHostname: false }).hostname).to.equal(
|
|
@@ -1032,4 +1048,114 @@ export default function test(
|
|
|
1032
1048
|
}
|
|
1033
1049
|
});
|
|
1034
1050
|
});
|
|
1051
|
+
|
|
1052
|
+
describe('options handling (regression for shared default-options reuse)', () => {
|
|
1053
|
+
// Calling a method with no options must behave identically to passing `{}`.
|
|
1054
|
+
// The no-options path now returns a shared cached defaults object instead of
|
|
1055
|
+
// allocating one per call; this guards that the shared object stays read-only.
|
|
1056
|
+
it('omitting options equals passing {} for every public method', () => {
|
|
1057
|
+
const url = 'https://sub.example.co.uk/path?q=1';
|
|
1058
|
+
expect(tldts.parse(url)).to.deep.equal(tldts.parse(url, {}));
|
|
1059
|
+
expect(tldts.getHostname(url)).to.equal(tldts.getHostname(url, {}));
|
|
1060
|
+
expect(tldts.getDomain(url)).to.equal(tldts.getDomain(url, {}));
|
|
1061
|
+
expect(tldts.getPublicSuffix(url)).to.equal(
|
|
1062
|
+
tldts.getPublicSuffix(url, {}),
|
|
1063
|
+
);
|
|
1064
|
+
expect(tldts.getSubdomain(url)).to.equal(tldts.getSubdomain(url, {}));
|
|
1065
|
+
expect(tldts.getDomainWithoutSuffix(url)).to.equal(
|
|
1066
|
+
tldts.getDomainWithoutSuffix(url, {}),
|
|
1067
|
+
);
|
|
1068
|
+
});
|
|
1069
|
+
|
|
1070
|
+
// A prior call with custom options must not corrupt the shared defaults that
|
|
1071
|
+
// a subsequent no-options call relies on (co.uk is ICANN in all packages).
|
|
1072
|
+
it('a custom-options call does not corrupt later default-options results', () => {
|
|
1073
|
+
const url = 'https://sub.example.co.uk/';
|
|
1074
|
+
const before = tldts.getDomain(url); // default options
|
|
1075
|
+
// interleave calls with assorted non-default options
|
|
1076
|
+
tldts.getDomain(url, {
|
|
1077
|
+
allowPrivateDomains: true,
|
|
1078
|
+
validateHostname: false,
|
|
1079
|
+
detectIp: false,
|
|
1080
|
+
});
|
|
1081
|
+
tldts.getDomain('https://other.example.com/', { mixedInputs: false });
|
|
1082
|
+
const after = tldts.getDomain(url); // default options again
|
|
1083
|
+
expect(after).to.equal(before);
|
|
1084
|
+
expect(after).to.equal('example.co.uk');
|
|
1085
|
+
});
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
describe('public-suffix reconstruction (single-slice offset)', () => {
|
|
1089
|
+
// Rules match across multiple labels: the suffix is rebuilt via a single
|
|
1090
|
+
// hostname.slice at the computed offset (was parts.slice(i).join('.')).
|
|
1091
|
+
it('returns a multi-label rules suffix unchanged', () => {
|
|
1092
|
+
expect(tldts.getPublicSuffix('not.evil.co.uk')).to.equal('co.uk');
|
|
1093
|
+
expect(tldts.getDomain('a.b.c.example.co.uk')).to.equal('example.co.uk');
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
// Exception match: suffix offset uses index+1 (the exception removes its
|
|
1097
|
+
// own left-most label, e.g. !www.ck -> suffix 'ck').
|
|
1098
|
+
it('returns an exception suffix unchanged', () => {
|
|
1099
|
+
expect(tldts.getPublicSuffix('www.ck')).to.equal('ck');
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
|
|
1103
|
+
describe('hostname validation dedupe', () => {
|
|
1104
|
+
// Already-valid lowercase hostname: extractHostname returns the SAME string
|
|
1105
|
+
// reference, so the post-extraction validation is skipped — result must
|
|
1106
|
+
// still be that hostname.
|
|
1107
|
+
it('keeps an already-valid hostname', () => {
|
|
1108
|
+
expect(tldts.getHostname('example.co.uk')).to.equal('example.co.uk');
|
|
1109
|
+
expect(tldts.getHostname('sub.example.com')).to.equal('sub.example.com');
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
// Trailing dot is trimmed by extractHostname -> returned string differs from
|
|
1113
|
+
// the input -> the skip guard must NOT fire -> trimmed hostname is validated.
|
|
1114
|
+
it('still validates a trailing-dot hostname (guard does not fire)', () => {
|
|
1115
|
+
expect(tldts.getHostname('miam.miam.google.com.')).to.equal(
|
|
1116
|
+
'miam.miam.google.com',
|
|
1117
|
+
);
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
// Uppercase input is not a "valid hostname" to the validator, so the full
|
|
1121
|
+
// extraction + lowercasing path runs and the guard does not fire.
|
|
1122
|
+
it('lowercases an uppercase hostname', () => {
|
|
1123
|
+
expect(tldts.getHostname('EXAMPLE.COM')).to.equal('example.com');
|
|
1124
|
+
});
|
|
1125
|
+
|
|
1126
|
+
// An invalid hostname must still be rejected: the guard only skips the
|
|
1127
|
+
// re-scan when the input was ALREADY valid, so it can never keep an invalid one.
|
|
1128
|
+
it('still rejects an invalid hostname', () => {
|
|
1129
|
+
expect(tldts.getHostname('foo-.com')).to.equal(null);
|
|
1130
|
+
});
|
|
1131
|
+
});
|
|
1132
|
+
|
|
1133
|
+
describe('wildcard suffix reconstruction', () => {
|
|
1134
|
+
// *.sch.uk where the matched suffix spans every label of the hostname:
|
|
1135
|
+
// in the packed-hash impl this takes the backward-scan fallback branch
|
|
1136
|
+
// (matchLabels === number of hashed labels). Must return the full suffix.
|
|
1137
|
+
it('returns a wildcard suffix that spans the whole hostname', () => {
|
|
1138
|
+
expect(tldts.getPublicSuffix('foo.sch.uk')).to.equal('foo.sch.uk');
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
// *.sch.uk with an extra leading label (non-fallback wildcard branch).
|
|
1142
|
+
it('returns a wildcard suffix with a leading subdomain present', () => {
|
|
1143
|
+
expect(tldts.getPublicSuffix('pupils.school.sch.uk')).to.equal(
|
|
1144
|
+
'school.sch.uk',
|
|
1145
|
+
);
|
|
1146
|
+
});
|
|
1147
|
+
});
|
|
1148
|
+
|
|
1149
|
+
describe('prototype-pollution-safe trie traversal', () => {
|
|
1150
|
+
// A label equal to an Object.prototype member, sitting where the trie has a
|
|
1151
|
+
// '*' wildcard child (*.ck), must match the wildcard — NOT resolve to
|
|
1152
|
+
// Object.prototype.constructor / the __proto__ accessor. Guards the
|
|
1153
|
+
// hasOwnProperty check (or, post-Stage-2, the substring-keyed lookup).
|
|
1154
|
+
it('treats constructor/__proto__ labels as ordinary labels under a wildcard', () => {
|
|
1155
|
+
expect(tldts.getPublicSuffix('b.constructor.ck')).to.equal(
|
|
1156
|
+
'constructor.ck',
|
|
1157
|
+
);
|
|
1158
|
+
expect(tldts.getPublicSuffix('b.__proto__.ck')).to.equal('__proto__.ck');
|
|
1159
|
+
});
|
|
1160
|
+
});
|
|
1035
1161
|
}
|