Skip to content

Commit d44a8cb

Browse files
committed
Guard against bogus data.
* When decoding, make sure the resulting number is smaller than a 32 bit unsigned int, otherwise the data is not valid * When encoding, fixes bug where numbers where interpreted as signed numbers.
1 parent 69f0c89 commit d44a8cb

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

lib/base85.js

+16-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ var stream = require('stream');
33
var ENC_START = '<~';
44
var ENC_END = '~>';
55

6+
var NUM_MAXVALUE = Math.pow(2, 32) - 1;
7+
68
function encode_buffer(buffer)
79
{
810
var padding = (buffer.length % 4 === 0) ? 0 : 4 - buffer.length % 4;
@@ -11,10 +13,11 @@ function encode_buffer(buffer)
1113
for (var i = 0; i < buffer.length; i += 4) {
1214

1315
/* 32 bit number of the current 4 bytes (padded with 0 as necessary) */
14-
var num = (buffer[i] << 24) +
15-
((i + 1 > buffer.length ? 0 : buffer[i + 1]) << 16) +
16-
((i + 2 > buffer.length ? 0 : buffer[i + 2]) << 8) +
17-
((i + 3 > buffer.length ? 0 : buffer[i + 3]) << 0);
16+
var num = ((buffer[i] << 24) >>> 0) + // Shift right to force unsigned number
17+
(((i + 1 > buffer.length ? 0 : buffer[i + 1]) << 16) >>> 0) +
18+
(((i + 2 > buffer.length ? 0 : buffer[i + 2]) << 8) >>> 0) +
19+
(((i + 3 > buffer.length ? 0 : buffer[i + 3]) << 0) >>> 0);
20+
1821

1922
/* Create 5 characters from '!' to 'u' alphabet */
2023
var block = [];
@@ -48,10 +51,15 @@ function decode_buffer(buffer)
4851

4952
for (var i = bufferStart; i < bufferEnd; i += 5) {
5053
var num = ((buffer[i] - 33) * 85 * 85 * 85 * 85) +
51-
((i + 1 > bufferEnd ? 84 : (buffer[i + 1] - 33)) * 85 * 85 * 85) +
52-
((i + 2 > bufferEnd ? 84 : (buffer[i + 2] - 33)) * 85 * 85) +
53-
((i + 3 > bufferEnd ? 84 : (buffer[i + 3] - 33)) * 85) +
54-
((i + 4 > bufferEnd ? 84 : (buffer[i + 4] - 33)));
54+
((i + 1 >= bufferEnd ? 84 : (buffer[i + 1] - 33)) * 85 * 85 * 85) +
55+
((i + 2 >= bufferEnd ? 84 : (buffer[i + 2] - 33)) * 85 * 85) +
56+
((i + 3 >= bufferEnd ? 84 : (buffer[i + 3] - 33)) * 85) +
57+
((i + 4 >= bufferEnd ? 84 : (buffer[i + 4] - 33)));
58+
59+
if (num > NUM_MAXVALUE) {
60+
/* Bogus data, no encoding can have a value larger than NUM_MAXVALUE */
61+
return false;
62+
}
5563

5664
result.writeUInt32BE(num, 4 * Math.ceil((i - bufferStart) / 5));
5765
}

tests/data.js

+8
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,13 @@ exports.data = [
3434
{
3535
'raw' : new Buffer('Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.', 'ascii'),
3636
'enc' : '<~9jqo^BlbD-BleB1DJ+*+F(f,q/0JhKF<GL>[email protected]$d7F!,L7@<6@)/0JDEF<G%<+EV:2F!,O<DJ+*.@<*K0@<6L(Df-\\0Ec5e;DffZ(EZee.Bl.9pF"AGXBPCsi+DGm>@3BB/F*&OCAfu2/AKYi(DIb:@FD,*)+C]U=@3BN#EcYf8ATD3s@q?d$AftVqCh[NqF<G:8+EV:.+Cf>-FD5W8ARlolDIal(DId<j@<?3r@:F%a+D58\'ATD4$Bl@l3De:,-DJs`8ARoFb/0JMK@qB4^F!,R<AKZ&-DfTqBG%G>uD.RTpAKYo\'+CT/5+Cei#DII?(E,9)oF*2M7/c~>'
37+
},
38+
{
39+
'raw' : new Buffer([0xff]),
40+
'enc' : '<~rr~>'
41+
},
42+
{
43+
'raw' : new Buffer([0xff, 0xff, 0xff, 0xff]),
44+
'enc' : '<~s8W-!~>'
3745
}
3846
];

tests/decode.js

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ var data = require('./data').data;
55
exports.testErrors = function(test)
66
{
77
test.equal(base85.decode(1234), false)
8+
test.equal(base85.decode('<~u~>'), false);
9+
test.equal(base85.decode('<~uuuuu~>'), false);
810
test.done();
911
}
1012

0 commit comments

Comments
 (0)