Skip to content

Commit

Permalink
Fix issue keichi#16 where string parser was broken
Browse files Browse the repository at this point in the history
  • Loading branch information
keichi committed Jun 5, 2015
1 parent e401454 commit cc53ac3
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
39 changes: 26 additions & 13 deletions lib/binary_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,10 @@ Parser.prototype.skip = function(length, options) {

Parser.prototype.string = function(varName, options) {
if (!options.zeroTerminated && !options.length) {
throw new Error('Length option of string is not defined.');
throw new Error('Neiter length nor zeroTerminated is defined for string.');
}
if (options.stripNull && !options.length) {
throw new Error('Length must be defined if stripNull is defined.');
}
options.encoding = options.encoding || 'utf8';

Expand Down Expand Up @@ -398,30 +401,40 @@ Parser.prototype.generateSkip = function(ctx) {
};

Parser.prototype.generateString = function(ctx) {
if(this.options.length) {
var name = ctx.generateVariable(this.varName);
var name = ctx.generateVariable(this.varName);
var start = ctx.generateTmpVariable();

if (this.options.length && this.options.zeroTerminated) {
ctx.pushCode('var {0} = offset;', start);
ctx.pushCode('while(buffer.readUInt8(offset++) !== 0 && offset - {0} < {1});',
start,
this.options.length
);
ctx.pushCode('{0} = buffer.toString(\'{1}\', {2}, offset - {2} < {3} ? offset - 1 : offset);',
name,
this.options.encoding,
start,
this.options.length
);
} else if(this.options.length) {
ctx.pushCode('{0} = buffer.toString(\'{1}\', offset, offset + {2});',
name,
this.options.encoding,
ctx.generateOption(this.options.length)
);
if(this.options.stripNull)
{
ctx.pushCode('{0} = {0}.replace(/\0/g, \'\')', name);
}
ctx.pushCode('offset += {0};', ctx.generateOption(this.options.length));
}
else {
var start = ctx.generateTmpVariable();

} else if (this.options.zeroTerminated) {
ctx.pushCode('var {0} = offset;', start);
ctx.pushCode('while(buffer.readUInt8(offset++) !== 0);');
ctx.pushCode('{0} = buffer.toString(\'{1}\', {2}, offset - 1);',
ctx.generateVariable(this.varName),
name,
this.options.encoding,
start
);
}
if(this.options.stripNull) {
ctx.pushCode('{0} = {0}.replace(/\\x00+$/g, \'\')', name);
}
};

Parser.prototype.generateBuffer = function(ctx) {
Expand Down Expand Up @@ -536,7 +549,7 @@ Parser.prototype.generateFormatter = function(ctx, varName, formatter) {
if (typeof formatter === 'function') {
ctx.pushCode('{0} = ({1}).call(this, {0});', varName, formatter);
}
}
};

Parser.prototype.isInteger = function() {
return !!this.type.match(/U?Int[8|16|32][BE|LE]?|Bit\d+/);
Expand Down
21 changes: 21 additions & 0 deletions test/primitive_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,27 @@ describe('Primitive parser', function(){

assert.deepEqual(parser.parse(buffer), {msg: 'hello, world'});
});
it('should parser zero terminated fixed-length string', function() {
var buffer = new Buffer('abc\u0000defghij\u0000');
var parser = Parser.start()
.string('a', {length: 5, zeroTerminated: true})
.string('b', {length: 5, zeroTerminated: true})
.string('c', {length: 5, zeroTerminated: true})

assert.deepEqual(parser.parse(buffer), {
a: 'abc',
b: 'defgh',
c: 'ij'
});
});
it('should strip trailing null characters', function() {
var buffer = new Buffer('746573740000', 'hex');
var parser1 = Parser.start().string('str', {length: 7, stripNull: false});
var parser2 = Parser.start().string('str', {length: 7, stripNull: true});

assert.equal(parser1.parse(buffer).str, 'test\u0000\u0000');
assert.equal(parser2.parse(buffer).str, 'test');
});
});

describe('Buffer parser', function() {
Expand Down

0 comments on commit cc53ac3

Please sign in to comment.