Skip to content

Commit

Permalink
fix: fix converting strings to IP addresses and back again (#270)
Browse files Browse the repository at this point in the history
Partial fix for the issues observed in the ipfs interop suite - windows seems to lose it's reference to the results variable during node startup, but only windows. Instead return the result from the scope in which is is created.
  • Loading branch information
achingbrain authored Sep 21, 2022
1 parent 36de98f commit 77f063a
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
4 changes: 2 additions & 2 deletions src/convert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const anybaseDecoder = (function () {

function ip2bytes (ipString: string) {
if (!ip.isIP(ipString)) {
throw new Error(`invalid ip address "${ipString}"`)
throw new Error('invalid ip address')
}
return ip.toBytes(ipString)
}
Expand All @@ -114,7 +114,7 @@ function bytes2ip (ipBuff: Uint8Array) {
throw new Error('ipBuff is required')
}
if (!ip.isIP(ipString)) {
throw new Error(`invalid ip address "${ipString}"`)
throw new Error('invalid ip address')
}
return ipString
}
Expand Down
50 changes: 30 additions & 20 deletions src/ip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,19 @@ export const isV6 = isIPv6
// but with buf/offset args removed because we don't use them
export const toBytes = function (ip: string): Uint8Array {
let offset = 0
let result
ip = ip.trim()
ip = ip.toString().trim()

if (isV4(ip)) {
result = new Uint8Array(offset + 4)
const bytes = new Uint8Array(offset + 4)

ip.split(/\./g).forEach((byte) => {
result[offset++] = parseInt(byte, 10) & 0xff
bytes[offset++] = parseInt(byte, 10) & 0xff
})
} else if (isV6(ip)) {

return bytes
}

if (isV6(ip)) {
const sections = ip.split(':', 8)

let i
Expand Down Expand Up @@ -48,44 +52,50 @@ export const toBytes = function (ip: string): Uint8Array {
sections.splice.apply(sections, argv)
}

result = new Uint8Array(offset + 16)
const bytes = new Uint8Array(offset + 16)

for (i = 0; i < sections.length; i++) {
const word = parseInt(sections[i], 16)
result[offset++] = (word >> 8) & 0xff
result[offset++] = word & 0xff
bytes[offset++] = (word >> 8) & 0xff
bytes[offset++] = word & 0xff
}
}

if (result == null) {
throw new Error(`invalid ip address "${ip}"`)
return bytes
}

return result
throw new Error('invalid ip address')
}

// Copied from https://github.com/indutny/node-ip/blob/master/lib/ip.js#L63
export const toString = function (buf: Uint8Array, offset: number = 0, length?: number) {
offset = ~~offset
length = length ?? (buf.length - offset)

const result = []
let string = ''
const view = new DataView(buf.buffer)

if (length === 4) {
const result = []

// IPv4
for (let i = 0; i < length; i++) {
result.push(buf[offset + i])
}
string = result.join('.')
} else if (length === 16) {

return result.join('.')
}

if (length === 16) {
const result = []

// IPv6
for (let i = 0; i < length; i += 2) {
result.push(view.getUint16(offset + i).toString(16))
}
string = result.join(':')
string = string.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3')
string = string.replace(/:{3,4}/, '::')

return result.join(':')
.replace(/(^|:)0(:0)*:0(:|$)/, '$1::$3')
.replace(/:{3,4}/, '::')
}

return string
return ''
}

0 comments on commit 77f063a

Please sign in to comment.