Skip to content

Commit c99d6eb

Browse files
authored
Merge pull request #14 from NodeRedis/v.2.1.0
V.2.1.0 Fixes #12 Closes #10 Closes #13
2 parents 926d8c6 + 09ca39e commit c99d6eb

File tree

5 files changed

+142
-243
lines changed

5 files changed

+142
-243
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ addons:
99
packages:
1010
- g++-4.8
1111
node_js:
12-
- "0.10"
13-
- "0.12"
1412
- "4"
1513
- "6"
14+
- "7"
1615
install:
1716
- npm install
1817
- npm install hiredis

changelog.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## v.2.1.0 - xx Oct, 2016
2+
3+
Features
4+
5+
- Improve parser errors by adding more detailed information to them
6+
- Accept manipulated Object.prototypes
7+
- Unref the interval if used
8+
19
## v.2.0.4 - 21 Jul, 2016
210

311
Bugfixes

lib/parser.js

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,15 @@ function parseStringNumbers (parser) {
6363
/**
6464
* Returns a string or buffer of the provided offset start and
6565
* end ranges. Checks `optionReturnBuffers`.
66+
*
67+
* If returnBuffers is active, all return values are returned as buffers besides numbers and errors
68+
*
6669
* @param parser
6770
* @param start
6871
* @param end
6972
* @returns {*}
7073
*/
7174
function convertBufferRange (parser, start, end) {
72-
// If returnBuffers is active, all return values are returned as buffers besides numbers and errors
7375
parser.offset = end + 2
7476
if (parser.optionReturnBuffers === true) {
7577
return parser.buffer.slice(start, end)
@@ -111,13 +113,15 @@ function parseLength (parser) {
111113

112114
/**
113115
* Parse a ':' redis integer response
116+
*
117+
* If stringNumbers is activated the parser always returns numbers as string
118+
* This is important for big numbers (number > Math.pow(2, 53)) as js numbers
119+
* are 64bit floating point numbers with reduced precision
120+
*
114121
* @param parser
115122
* @returns {*}
116123
*/
117124
function parseInteger (parser) {
118-
// If stringNumbers is activated the parser always returns numbers as string
119-
// This is important for big numbers (number > Math.pow(2, 53)) as js numbers
120-
// are 64bit floating point numbers with reduced precision
121125
if (parser.optionStringNumbers) {
122126
return parseStringNumbers(parser)
123127
}
@@ -223,7 +227,10 @@ function parseType (parser, type) {
223227
case 45: // -
224228
return parseError(parser)
225229
default:
226-
return handleError(parser, new ReplyError('Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte'))
230+
const err = new ReplyError('Protocol error, got ' + JSON.stringify(String.fromCharCode(type)) + ' as reply type byte', 20)
231+
err.offset = parser.offset
232+
err.buffer = JSON.stringify(parser.buffer)
233+
return handleError(parser, err)
227234
}
228235
}
229236

@@ -250,7 +257,7 @@ function JavascriptRedisParser (options) {
250257
throw new TypeError('Please provide all return functions while initiating the parser')
251258
}
252259
for (var key in options) {
253-
if (typeof options[key] !== optionTypes[key]) {
260+
if (optionTypes.hasOwnProperty(key) && typeof options[key] !== optionTypes[key]) {
254261
throw new TypeError('The options argument contains the property "' + key + '" that is either unkown or of a wrong type')
255262
}
256263
}
@@ -280,13 +287,17 @@ function JavascriptRedisParser (options) {
280287

281288
/**
282289
* Concat a bulk string containing multiple chunks
290+
*
291+
* Notes:
292+
* 1) The first chunk might contain the whole bulk string including the \r
293+
* 2) We are only safe to fully add up elements that are neither the first nor any of the last two elements
294+
*
283295
* @param parser
284296
* @param buffer
285297
* @returns {String}
286298
*/
287299
function concatBulkString (parser) {
288300
var list = parser.bufferCache
289-
// The first chunk might contain the whole bulk string including the \r
290301
var chunks = list.length
291302
var offset = parser.bigStrSize - parser.totalChunkSize
292303
parser.offset = offset
@@ -299,7 +310,6 @@ function concatBulkString (parser) {
299310
}
300311
var res = decoder.write(list[0].slice(parser.bigOffset))
301312
for (var i = 1; i < chunks - 2; i++) {
302-
// We are only safe to fully add up elements that are neither the first nor any of the last two elements
303313
res += decoder.write(list[i])
304314
}
305315
res += decoder.end(list[i].slice(0, offset === 1 ? list[i].length - 1 : offset - 2))
@@ -314,8 +324,14 @@ function decreaseBufferPool () {
314324
if (bufferPool.length > 50 * 1024) {
315325
// Balance between increasing and decreasing the bufferPool
316326
if (counter === 1 || notDecreased > counter * 2) {
317-
// Decrease the bufferPool by 16kb by removing the first 16kb of the current pool
318-
bufferPool = bufferPool.slice(Math.floor(bufferPool.length / 10), bufferPool.length)
327+
// Decrease the bufferPool by 10% by removing the first 10% of the current pool
328+
var sliceLength = Math.floor(bufferPool.length / 10)
329+
if (bufferOffset <= sliceLength) {
330+
bufferOffset = 0
331+
} else {
332+
bufferOffset -= sliceLength
333+
}
334+
bufferPool = bufferPool.slice(sliceLength, bufferPool.length)
319335
} else {
320336
notDecreased++
321337
counter--
@@ -339,18 +355,17 @@ function concatBuffer (parser, length) {
339355
var pos = bufferOffset
340356
length -= parser.offset
341357
if (bufferPool.length < length + bufferOffset) {
342-
// Increase the bufferPool size by three times the current needed length
343-
var multiplier = 3
344-
if (bufferOffset > 1024 * 1024 * 200) {
358+
// Increase the bufferPool size
359+
var multiplier = length > 1024 * 1024 * 75 ? 2 : 3
360+
if (bufferOffset > 1024 * 1024 * 120) {
345361
bufferOffset = 1024 * 1024 * 50
346-
multiplier = 2
347362
}
348363
bufferPool = new Buffer(length * multiplier + bufferOffset)
349364
bufferOffset = 0
350365
counter++
351366
pos = 0
352367
if (interval === null) {
353-
interval = setInterval(decreaseBufferPool, 50)
368+
interval = setInterval(decreaseBufferPool, 50).unref()
354369
}
355370
}
356371
list[0].copy(bufferPool, pos, parser.offset, list[0].length)
@@ -369,7 +384,7 @@ function concatBuffer (parser, length) {
369384
* @param buffer
370385
* @returns {undefined}
371386
*/
372-
JavascriptRedisParser.prototype.execute = function (buffer) {
387+
JavascriptRedisParser.prototype.execute = function execute (buffer) {
373388
if (this.buffer === null) {
374389
this.buffer = buffer
375390
this.offset = 0
@@ -410,9 +425,9 @@ JavascriptRedisParser.prototype.execute = function (buffer) {
410425
}
411426

412427
if (type === 45) {
413-
this.returnError(response) // Errors -
428+
this.returnError(response)
414429
} else {
415-
this.returnReply(response) // Strings + // Integers : // Bulk strings $ // Arrays *
430+
this.returnReply(response)
416431
}
417432
}
418433

lib/replyError.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
var util = require('util')
44

5-
function ReplyError (message) {
5+
function ReplyError (message, newLimit) {
66
var limit = Error.stackTraceLimit
7-
Error.stackTraceLimit = 2
7+
Error.stackTraceLimit = newLimit || 2
8+
Error.call(this, message)
89
Error.captureStackTrace(this, this.constructor)
910
Error.stackTraceLimit = limit
1011
Object.defineProperty(this, 'message', {

0 commit comments

Comments
 (0)