Skip to content

Commit

Permalink
fix: fixed hostname validation for ending TLD in punycode, hostname #…
Browse files Browse the repository at this point in the history
  • Loading branch information
Kumar06Lav committed Oct 7, 2024
1 parent 342fc32 commit 8edc00f
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 6 deletions.
4 changes: 3 additions & 1 deletion deno/lib/__tests__/string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ test("passing validations", () => {
hostname.parse("www.google.com");
hostname.parse("[2001:db8::ff00:42:8329]");
hostname.parse("192.168.1.1");
hostname.parse("xn--d1acj3b");
hostname.parse("xn--d1acj3b.com");
hostname.parse("xn--d1acj3b.org");
});

test("failing validations", () => {
Expand All @@ -44,6 +45,7 @@ test("failing validations", () => {
expect(() => startsWith.parse("x")).toThrow();
expect(() => endsWith.parse("x")).toThrow();
expect(() => hostname.parse("ht!tp://invalid.com")).toThrow();
expect(() => hostname.parse("xn--d1acj3b")).toThrow();
expect(() => hostname.parse("xn--d1acj3b..com")).toThrow();
expect(() => hostname.parse("[email protected]")).toThrow();
expect(() => hostname.parse("[2001:db8::zzzz]")).toThrow();
Expand Down
4 changes: 2 additions & 2 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
} else if (check.kind === "hostname") {
const domainNameRegex =
/^(?!-)(?!.*--)(?!.*\.\.)(?!.*\.$)[a-zA-Z0-9-]{1,63}(?<!-)(\.[a-zA-Z0-9-]{1,63})*$/;
const punycodeRegex = /^xn--[a-zA-Z0-9-]{1,63}$/;
const punycodeRegex = /^xn--[a-zA-Z0-9-]{1,63}\.[a-zA-Z]{2,}$/; // Ensure TLD after punycode
const ipv4Regex =
/^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$/;
const ipv6Regex = /^\[[0-9a-fA-F:]+\]$/;
Expand All @@ -868,7 +868,7 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
domainNameRegex.test(input.data) ||
ipv4Regex.test(input.data) ||
ipv6Regex.test(input.data) ||
punycodeRegex.test(input.data);
punycodeRegex.test(input.data); // Apply punycodeRegex here

if (!isValid) {
ctx = this._getOrReturnCtx(input, ctx);
Expand Down
4 changes: 3 additions & 1 deletion src/__tests__/string.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ test("passing validations", () => {
hostname.parse("www.google.com");
hostname.parse("[2001:db8::ff00:42:8329]");
hostname.parse("192.168.1.1");
hostname.parse("xn--d1acj3b");
hostname.parse("xn--d1acj3b.com");
hostname.parse("xn--d1acj3b.org");
});

test("failing validations", () => {
Expand All @@ -43,6 +44,7 @@ test("failing validations", () => {
expect(() => startsWith.parse("x")).toThrow();
expect(() => endsWith.parse("x")).toThrow();
expect(() => hostname.parse("ht!tp://invalid.com")).toThrow();
expect(() => hostname.parse("xn--d1acj3b")).toThrow();
expect(() => hostname.parse("xn--d1acj3b..com")).toThrow();
expect(() => hostname.parse("[email protected]")).toThrow();
expect(() => hostname.parse("[2001:db8::zzzz]")).toThrow();
Expand Down
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
} else if (check.kind === "hostname") {
const domainNameRegex =
/^(?!-)(?!.*--)(?!.*\.\.)(?!.*\.$)[a-zA-Z0-9-]{1,63}(?<!-)(\.[a-zA-Z0-9-]{1,63})*$/;
const punycodeRegex = /^xn--[a-zA-Z0-9-]{1,63}$/;
const punycodeRegex = /^xn--[a-zA-Z0-9-]{1,63}\.[a-zA-Z]{2,}$/; // Ensure TLD after punycode
const ipv4Regex =
/^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)$/;
const ipv6Regex = /^\[[0-9a-fA-F:]+\]$/;
Expand All @@ -868,7 +868,7 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
domainNameRegex.test(input.data) ||
ipv4Regex.test(input.data) ||
ipv6Regex.test(input.data) ||
punycodeRegex.test(input.data);
punycodeRegex.test(input.data); // Apply punycodeRegex here

if (!isValid) {
ctx = this._getOrReturnCtx(input, ctx);
Expand Down

0 comments on commit 8edc00f

Please sign in to comment.