Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

email-address-validator

Go ReferenceCI

Package email checks an address against the Mailbox grammar of RFC 5321, the production an address must satisfy to appear in an SMTP MAIL or RCPT command. Validators commonly approximate this grammar with a regular expression; this package implements it directly, along with the length limits and errata that accompany it.

What it checks

  • The RFC 5321 Mailbox grammar: dot-string and quoted-string local parts, letter-digit-hyphen domain labels, and IPv4 and IPv6 address literals.
  • Length limits from RFC 5321 section 4.5.3.1 as corrected by RFC 3696 erratum 1690: a 64-octet local part, a 255-octet domain, and a 254-octet address.
  • With ValidateSMTPUTF8, the internationalization extensions of RFC 6531 and RFC 6532: well-formed UTF-8 in the local part and IDNA2008 U-labels in the domain, including the RFC 5892 derived-property and contextual rules.

Validation is syntactic. The package does not resolve DNS, apply IDN registry policy, or confirm that a mailbox exists. SPEC.md records the governing specifications, the rules enforced, and the judgment calls behind them.

Install

go get github.com/initialcapacity/email-address-validator

The import path ends in email-address-validator; the package name is email:

import email "github.com/initialcapacity/email-address-validator"

Usage

Validate and ValidateSMTPUTF8 return nil for a valid address. IsValid and IsValidSMTPUTF8 are boolean forms of the same checks.

iferr:=email.Validate("grace.hopper@example.com"); err!=nil {
log.Fatal(err)
}
email.IsValid("用户@example.com") // false: non-ASCII requires SMTPUTF8email.IsValidSMTPUTF8("用户@example.com") // true

Every failure is a *email.SyntaxError wrapping a sentinel error. Classify failures with errors.Is, then recover the byte offset of the fault with errors.As:

err:=email.Validate("ada@exa_mple.com")
iferrors.Is(err, email.ErrInvalidDomain) {
varsyntaxErr*email.SyntaxErroriferrors.As(err, &syntaxErr) {
fmt.Println(syntaxErr.Offset) // 7, the underscore
}
}

The package documentation lists the sentinel errors and holds runnable examples.

Reimplementing in another language

The repository doubles as a porting kit. REIMPLEMENTING.md lists what a port needs, and testdata/cases.json holds a language-agnostic conformance suite that CI runs against this implementation.

To start a port, give a coding agent this prompt, filling in the language:

Reimplement the email address validator from https://github.com/initialcapacity/email-address-validator in <language>. Clone or fetch the repository, then read REIMPLEMENTING.md, SPEC.md, and testdata/README.md, in that order, along with the RFC sections they cite. The Go source is the reference implementation.

Implement both validation modes: strict RFC 5321 (ASCII) and RFC 6531 (SMTPUTF8). Expose a boolean check and a diagnostic form that reports an error kind and a byte offset. Accept byte-string input so the base64-encoded cases run.

Write a conformance test that runs every case in testdata/cases.json through both modes, and iterate until both tiers pass in full: the accept/reject results must match valid.ascii and valid.smtputf8, and the diagnostics must match every errors entry, kind and offset. Fix the implementation, never the expectations, and do not special-case any vector. Use idiomatic tooling and project structure for <language>, and keep third-party dependencies to what the standard library cannot provide.

Development

Build and test with the standard Go toolchain, version 1.27 or later:

go build ./...
go test -race ./...

Before sending a change, run the same checks CI runs:

test -z "$(gofmt -l .)"
go vet ./...
go test -race ./...

unicode_tables.go holds case folding, Joining_Type, and virama data generated from the Unicode Character Database. A test fails when its version drifts from the standard library's; after a toolchain upgrade, regenerate it:

go run gen_unicode_tables.go -ucd /path/to/ucd -version 17.0.0

A fuzz target exercises the parser with arbitrary input and asserts that RFC 5321 validity implies RFC 6531 validity. CI runs it for 30 seconds; run it longer when changing the parser:

go test -fuzz=FuzzValidate -fuzztime=5m .

License

MIT; see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages