Skip to content

Commit 82ebe1f

Browse files
committed
add: base64url support
Using string replaceAll since base64 is external base64-js. Dependency does not yet support base64url beatgammit/base64-js#53
1 parent 795bbb5 commit 82ebe1f

3 files changed

Lines changed: 52 additions & 8 deletions

File tree

index.js

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ Buffer.isEncoding = function isEncoding (encoding) {
376376
case 'ascii':
377377
case 'latin1':
378378
case 'binary':
379+
case 'base64url':
379380
case 'base64':
380381
case 'ucs2':
381382
case 'ucs-2':
@@ -533,8 +534,9 @@ function slowToString (encoding, start, end) {
533534
case 'binary':
534535
return latin1Slice(this, start, end)
535536

537+
case 'base64url':
536538
case 'base64':
537-
return base64Slice(this, start, end)
539+
return base64Slice(this, start, end, encoding)
538540

539541
case 'ucs2':
540542
case 'ucs-2':
@@ -859,8 +861,9 @@ function asciiWrite (buf, string, offset, length) {
859861
return blitBuffer(asciiToBytes(string), buf, offset, length)
860862
}
861863

862-
function base64Write (buf, string, offset, length) {
863-
return blitBuffer(base64ToBytes(string), buf, offset, length)
864+
function base64Write (buf, string, offset, length, encoding) {
865+
const b64 = encoding === 'base64url' ? base64urlToBase64(string) : string
866+
return blitBuffer(base64ToBytes(b64), buf, offset, length)
864867
}
865868

866869
function ucs2Write (buf, string, offset, length) {
@@ -918,9 +921,11 @@ Buffer.prototype.write = function write (string, offset, length, encoding) {
918921
case 'binary':
919922
return asciiWrite(this, string, offset, length)
920923

924+
case 'base64url':
921925
case 'base64':
926+
// console.log(encoding, '::', string)
922927
// Warning: maxLength not taken into account in base64Write
923-
return base64Write(this, string, offset, length)
928+
return base64Write(this, string, offset, length, encoding)
924929

925930
case 'ucs2':
926931
case 'ucs-2':
@@ -943,12 +948,14 @@ Buffer.prototype.toJSON = function toJSON () {
943948
}
944949
}
945950

946-
function base64Slice (buf, start, end) {
951+
function base64Slice (buf, start, end, encoding) {
952+
let b64
947953
if (start === 0 && end === buf.length) {
948-
return base64.fromByteArray(buf)
954+
b64 = base64.fromByteArray(buf)
949955
} else {
950-
return base64.fromByteArray(buf.slice(start, end))
956+
b64 = base64.fromByteArray(buf.slice(start, end))
951957
}
958+
return encoding === 'base64url' ? base64urlFromBase64(b64) : b64
952959
}
953960

954961
function utf8Slice (buf, start, end) {
@@ -1939,6 +1946,23 @@ function boundsError (value, length, type) {
19391946

19401947
const INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
19411948

1949+
const BASE64_CHAR_62 = '+'
1950+
const BASE64_CHAR_63 = '/'
1951+
const BASE64URL_CHAR_62 = '-'
1952+
const BASE64URL_CHAR_63 = '_'
1953+
1954+
function base64urlToBase64 (str) {
1955+
return str
1956+
.replaceAll(BASE64URL_CHAR_62, BASE64_CHAR_62)
1957+
.replaceAll(BASE64URL_CHAR_63, BASE64_CHAR_63)
1958+
}
1959+
1960+
function base64urlFromBase64 (str) {
1961+
return str
1962+
.replaceAll(BASE64_CHAR_62, BASE64URL_CHAR_62)
1963+
.replaceAll(BASE64_CHAR_63, BASE64URL_CHAR_63)
1964+
}
1965+
19421966
function base64clean (str) {
19431967
// Node takes equal signs as end of the Base64 encoding
19441968
str = str.split('=')[0]

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@
6666
"test-browser-new": "airtap -- test/*.js test/node/*.js",
6767
"test-browser-new-local": "airtap --local -- test/*.js test/node/*.js",
6868
"test-node": "tape test/*.js test/node/*.js",
69-
"update-authors": "./bin/update-authors.sh"
69+
"update-authors": "./bin/update-authors.sh",
70+
"lint": "standard",
71+
"lint:fix": "standard --fix"
7072
},
7173
"standard": {
7274
"ignore": [

test/base64.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,21 @@ test('base64: high byte', function (t) {
5353
)
5454
t.end()
5555
})
56+
57+
test('base64url: convert to/from base64', function (t) {
58+
const base64url = '8J-Ps--4j_Cfj7PvuI8='
59+
const base64 = '8J+Ps++4j/Cfj7PvuI8='
60+
const text = '🏳️🏳️'
61+
62+
const base64urlBuf = new B(base64url, 'base64url')
63+
t.equal(base64urlBuf.toString('base64'), base64)
64+
t.equal(base64urlBuf.toString(), text)
65+
66+
const base64Buf = new B(base64, 'base64')
67+
t.equal(base64Buf.toString('base64url'), base64url)
68+
t.equal(base64Buf.toString(), text)
69+
70+
const buf = new B(text)
71+
t.equal(buf.toString('base64url'), base64url)
72+
t.end()
73+
})

0 commit comments

Comments
 (0)