Skip to content

Commit

Permalink
Merge branch 'float-encoding'
Browse files Browse the repository at this point in the history
  • Loading branch information
clayzermk1 committed May 19, 2018
2 parents a82ae00 + 4f89c88 commit 9827c7e
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 32 deletions.
9 changes: 3 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
language: node_js
node_js:
- '0.10'
- '0.12'
- '6.3'
before_install:
- npm install -g codeclimate-test-reporter
- '6'
- '8'
after_script:
- codeclimate-test-reporter < coverage/lcov.info
- npm run coverage && npm run codecov
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# 0.3.0
- Added support for floats (#8). Thank you @tgriesser!
- Added support for ISO-8859-1 encoded strings (#8, parsed as "binary"). Thank you @tgriesser!
- Updated dependencies.
- Removed Code Climate.
- Added test coverage with Codecov.
- Updated license copyright years.

# 0.2.3
- Fixed readme badge URLs (#7).

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2017 Clay Walker <[email protected]>
Copyright (c) 2017-2018 Clay Walker <[email protected]>
Copyright (c) 2014-2017 Own Group Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# node-marshal
[![Build Status](https://travis-ci.org/clayzermk1/node-marshal.svg)](https://travis-ci.org/clayzermk1/node-marshal)
[![Maintainability](https://api.codeclimate.com/v1/badges/aad4435e0049564ad670/maintainability)](https://codeclimate.com/github/clayzermk1/node-marshal/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/aad4435e0049564ad670/test_coverage)](https://codeclimate.com/github/clayzermk1/node-marshal/test_coverage)
[![codecov](https://codecov.io/gh/clayzermk1/node-marshal/branch/master/graph/badge.svg)](https://codecov.io/gh/clayzermk1/node-marshal)

Parse Ruby's Marshal strings into JavaScript objects/JSON.

Expand Down Expand Up @@ -38,7 +37,8 @@ _**Unable**_ to convert a JavaScript object into a Marshal string. i.e. `Marshal
* `nil` (converted to `null`)
* booleans
* integers
* bignums
* floats (thank you [\@tgriesser](https://github.com/tgriesser)!)
* bignums (bignums are broken after v0.2.0, if you need bignum support please use v0.2.0)
* raw strings
* symbols
* symbol links
Expand All @@ -50,7 +50,6 @@ _**Unable**_ to convert a JavaScript object into a Marshal string. i.e. `Marshal

### Unsupported Types

* floats
* classes
* modules
* regular expressions
Expand Down
59 changes: 45 additions & 14 deletions lib/marshal.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Marshal = (function () {
return this._parseHash();
case 0x6C: // l - bignum
return this._parseBignum();
case 0x66: // f - float
return this._parseFloat();
case 0x2F: // / - regexp
case 0x63: // c - class
case 0x6D: // m - module
Expand All @@ -53,6 +55,40 @@ Marshal = (function () {
}
};

Marshal.prototype._getLength = function () {
var length = this.buffer.readInt8(this._index++); // read the number of "machine words" - 16bit integers
if (length === 0) {
length = 0;
}
else if (length >= 6) {
length = length - 5;
}
else if (length <= -6) {
length = length + 5;
}
return length;
};

/** Parse a float.
* @return The decoded float.
*/
Marshal.prototype._parseFloat = function () {
var length = this._getLength();
var floatValue = this.buffer.slice(this._index, this._index + length);
this._index = this._index + length;
if (floatValue.toString('utf8') === 'inf') {
return Infinity;
}
if (floatValue.toString('utf8') === '-inf') {
return -Infinity;
}
if (floatValue.toString('utf8') === 'nan') {
return NaN;
}
return parseFloat(floatValue.toString('utf8'));
};


/** Parse a bignum.
* @return The decoded bignum.
*/
Expand All @@ -61,16 +97,7 @@ Marshal = (function () {
debug('isNegative: %s', isNegative);

// the word length appears to always be positive but still follows the Marshal length logic
var wordLength = this.buffer.readInt8(this._index++); // read the number of "machine words" - 16bit integers
if (wordLength === 0) {
wordLength = 0;
}
else if (wordLength >= 6) {
wordLength = wordLength - 5;
}
else if (wordLength <= -6) {
wordLength = wordLength + 5;
}
var wordLength = this._getLength();
debug('wordLength: %s', wordLength);

// it appears that words are always zero padded - no odd number of bytes
Expand Down Expand Up @@ -261,8 +288,8 @@ Marshal = (function () {
var value = this._parse();
this._objects.push(value); // values are saved in the object cache before the ivar

if (symbol === "E") {
// E means we have a common encoding, the following boolean determines UTF-8 or ASCII
if (symbol === 'E') {
// 'E' means we have a common encoding, the following boolean determines UTF-8 or ASCII
if (value === true) {
encoding = 'utf8';
}
Expand All @@ -271,8 +298,12 @@ Marshal = (function () {
}
}
else if (symbol === 'encoding') {
// encoding means we have some other encoding
encoding = value;
// 'encoding' means we have some other encoding
if (value === 'ISO-8859-1') {
encoding = 'binary';
} else {
encoding = value;
}
}
else {
throw new MarshalError('invalid IVAR encoding specification ' + symbol, this);
Expand Down
18 changes: 11 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"name": "marshal",
"version": "0.2.3",
"version": "0.3.0",
"description": "Parse Ruby's Marshal strings into JavaScript objects/JSON.",
"main": "index.js",
"scripts": {
"test": "tape test/*.js"
"codecov": "codecov -f ./coverage/lcov.info -t 89a2b49e-cb3c-4349-91c0-3403e4a75303 --disable=gcov",
"coverage": "nyc report --reporter=lcov",
"test": "nyc tape test/*.js"
},
"repository": {
"type": "git",
Expand All @@ -23,12 +25,14 @@
},
"homepage": "https://github.com/clayzermk1/node-marshal",
"engines": {
"node": ">=0.10.0 <=6.3.1"
},
"devDependencies": {
"tape": "^4.6.0"
"node": "^6.11.5"
},
"dependencies": {
"debug": "^2.2.0"
"debug": "3.1.0"
},
"devDependencies": {
"codecov": "3.0.2",
"nyc": "11.8.0",
"tape": "4.9.0"
}
}
35 changes: 35 additions & 0 deletions test/marshal.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var stringyEmpty = new Buffer('04082200', 'hex');
var stringyHello = new Buffer('0408220a68656c6c6f', 'hex');
var ivaryHelloUtf = new Buffer('040849220a68656c6c6f063a064554', 'hex');
var ivaryHelloAscii = new Buffer('040849220a68656c6c6f063a064546', 'hex');
var ivaryHelloIso8859Dash1 = new Buffer('040849220a68656c6c6f063a0d656e636f64696e67220f49534f2d383835392d31', 'hex');
var ivaryLorem = new Buffer('04082201f64c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69742e20526570656c6c617420766f6c757074617320726572756d20656f7320656c6967656e64692c20647563696d7573206c61626f72756d206578706c696361626f2074656d706f72696275732076656c206970736120657865726369746174696f6e656d2070726f766964656e74206f62636165636174692065756d206c61626f72652065787065646974612061747175652c20646f6c6f72656d717565206c61626f72696f73616d206e6973692c20726570726568656e64657269742e063a064554', 'hex');
var arrayyEmpty = new Buffer('04085b00', 'hex');
var arrayyInteger = new Buffer('04085b066906', 'hex');
Expand All @@ -41,6 +42,11 @@ var objectyFoo = new Buffer('04086f3a0b4f626a656374063a0940666f6f492208626172063
var hashyEmpty = new Buffer('04087b00', 'hex');
var hashyOneTwo = new Buffer('04087b0669066907', 'hex');
var railsSessionCookie = new Buffer('04087b0b49220f73657373696f6e5f6964063a0645544922253836663666666139323537363739653231633733306236376138626263363233063b00544922105f637372665f746f6b656e063b004649223175557364487970586e6576346a6a4932646f554271317049795270637a5959536c443968354c78445a51553d063b004649220c757365725f6964063b004649220196636f6e6e6563742e736573733d732533416a2533412537422532327573657225323225334125323230313631626663652d616665302d346239652d386265382d6530323637653263646465322532322537442e4c4664327a652532465973316750744979456f597257665861747464633144774a353469576c332532462532426a6b35553b20506174683d2f3b20487474704f6e6c79063b005449221270617373776f72645f68617368063b00464922253334666263633762663264306265613335356164373938653032383938663563063b00464922106c6f636174696f6e5f6964063b004649222932356239306561632d303736392d343864382d393866612d383861343863633830376138063b005449220f6163636f756e745f6964063b004649222939363661656139662d636266302d346137392d383061642d623131633966393565626130063b0054', 'hex');
var floatyPositive = new Buffer('0408660c31322e33343536', 'hex');
var floatyNegative = new Buffer('0408660d2d31322e33343536', 'hex');
var floatyPositiveInfinity = new Buffer('04086608696e66', 'hex');
var floatyNegativeInfinity = new Buffer('040866092d696e66', 'hex');
var floatyNaN = new Buffer('040866086e616e', 'hex');

test('marshal', function (t) {
t.test('parse', function (t) {
Expand Down Expand Up @@ -195,6 +201,10 @@ test('marshal', function (t) {
t.equal('' + m.load(ivaryHelloAscii).parsed, 'hello', 'should equal "hello"');
t.end();
});
t.test('hello (ISO-8859-1)', function (t) {
t.equal('' + m.load(ivaryHelloIso8859Dash1).parsed, 'hello', 'should equal "hello"');
t.end();
});
t.test('lorem', function (t) {
t.equal('' + m.load(ivaryLorem).parsed, 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat voluptas rerum eos eligendi, ducimus laborum explicabo temporibus vel ipsa exercitationem provident obcaecati eum labore expedita atque, doloremque laboriosam nisi, reprehenderit.', 'should be "Lorem ipsum ..."');
t.end();
Expand Down Expand Up @@ -249,6 +259,31 @@ test('marshal', function (t) {
});
t.end();
});

t.test('floats', function (t) {
t.test('positive float', function (t) {
t.equal(m.load(floatyPositive).parsed, 12.3456, 'should equal 12.3456');
t.end();
});
t.test('negative float', function (t) {
t.equal(m.load(floatyNegative).parsed, -12.3456, 'should equal -12.3456');
t.end();
});
t.test('positive infinity', function (t) {
t.equal(m.load(floatyPositiveInfinity).parsed, Infinity, 'should equal Infinity');
t.end();
});
t.test('negative infinity', function (t) {
t.equal(m.load(floatyNegativeInfinity).parsed, -Infinity, 'should equal -Infinity');
t.end();
});
t.test('NaN', function (t) {
t.equal(Number.isNaN(m.load(floatyNaN).parsed), true, 'should equal NaN');
t.end();
});
t.end();
});

t.end();
});
t.end();
Expand Down

0 comments on commit 9827c7e

Please sign in to comment.