Skip to content

Commit

Permalink
perf: make ipv4 regex faster (#73)
Browse files Browse the repository at this point in the history
* perf: make ipv4 regex faster

All credits for this regex to https://stackoverflow.com/a/36760050. 

The regex is both more correct and faster (https://esbench.com/bench/6532596e7ff73700a4debb6a).
Examples:
previous regex recognized "01.01.01.01" or "1.1.000.1" as correct ipv4 regex, but those aren't valid as per https://datatracker.ietf.org/doc/html/rfc5954#section-4.1.

* avoid capture groups

* update to fastest regexp variant

* comment out 10.10.000.1110

* lint

---------

Signed-off-by: Jacob Groß <[email protected]>
Co-authored-by: Gürgün Dayıoğlu <[email protected]>
  • Loading branch information
kurtextrem and gurgunday authored Jun 7, 2024
1 parent 14b617f commit 787a904
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 5 deletions.
2 changes: 1 addition & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { HEX } = require('./scopedChars')

function normalizeIPv4 (host) {
if (findToken(host, '.') < 3) { return { host, isIPV4: false } }
const matches = host.match(/^(\b[01]?\d{1,2}|\b2[0-4]\d|\b25[0-5])(\.([01]?\d{1,2}|2[0-4]\d|25[0-5])){3}$/u) || []
const matches = host.match(/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/u) || []
const [address] = matches
if (address) {
return { host: stripLeadingZeros(address, '.'), isIPV4: true }
Expand Down
2 changes: 1 addition & 1 deletion test/compatibility.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ test('compatibility Parse', (t) => {
'//www.g.com/error\n/bleh/bleh',
'https://fastify.org',
'//10.10.10.10',
'//10.10.000.10',
// '//10.10.000.10', <-- not a valid URI per URI spec: https://datatracker.ietf.org/doc/html/rfc5954#section-4.1
'//[2001:db8::7%en0]',
'//[2001:dbZ::1]:80',
'//[2001:db8::1]:80',
Expand Down
15 changes: 12 additions & 3 deletions test/parse.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,21 @@ test('URI parse', (t) => {
t.equal(components.query, undefined, 'query')
t.equal(components.fragment, undefined, 'fragment')

// IPv4address with unformated 0
components = URI.parse('//10.10.000.10')
// IPv4address with unformated 0 stay as-is
components = URI.parse('//10.10.000.10') // not valid as per https://datatracker.ietf.org/doc/html/rfc5954#section-4.1
t.equal(components.error, undefined, 'IPv4address errors')
t.equal(components.scheme, undefined, 'scheme')
t.equal(components.userinfo, undefined, 'userinfo')
t.equal(components.host, '10.10.0.10', 'host')
t.equal(components.host, '10.10.000.10', 'host')
t.equal(components.port, undefined, 'port')
t.equal(components.path, '', 'path')
t.equal(components.query, undefined, 'query')
t.equal(components.fragment, undefined, 'fragment')
components = URI.parse('//01.01.01.01') // not valid in URIs: https://datatracker.ietf.org/doc/html/rfc3986#section-7.4
t.equal(components.error, undefined, 'IPv4address errors')
t.equal(components.scheme, undefined, 'scheme')
t.equal(components.userinfo, undefined, 'userinfo')
t.equal(components.host, '01.01.01.01', 'host')
t.equal(components.port, undefined, 'port')
t.equal(components.path, '', 'path')
t.equal(components.query, undefined, 'query')
Expand Down

0 comments on commit 787a904

Please sign in to comment.