diff --git a/.gitignore b/.gitignore index a72b52e..fd24291 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ lib-cov *.out *.pid *.gz - +.idea/ pids logs results diff --git a/php-unserialize.js b/php-unserialize.js index b87c447..bb6198b 100644 --- a/php-unserialize.js +++ b/php-unserialize.js @@ -15,6 +15,23 @@ exports.unserializeSession = unserializeSession; * @return unserialized data * @throws */ +function nth_occurrence (string, char, nth) { + var first_index = string.indexOf(char); + var length_up_to_first_index = first_index + 1; + + if (nth == 1) { + return first_index; + } else { + var string_after_first_occurrence = string.slice(length_up_to_first_index); + var next_occurrence = nth_occurrence(string_after_first_occurrence, char, nth - 1); + + if (next_occurrence === -1) { + return -1; + } else { + return length_up_to_first_index + next_occurrence; + } + } +} function unserialize (data) { // http://kevin.vanzonneveld.net // + original by: Arpad Ray (mailto:arpad@php.net) @@ -138,7 +155,33 @@ function unserialize (data) { error('SyntaxError', 'String length mismatch'); } break; - case 'a': + case 'o': + var objectIndex=nth_occurrence(data,':',3); + data='a'+data.substring(objectIndex); + readdata = {}; + + keyandchrs = read_until(data, dataoffset, ':'); + chrs = keyandchrs[0]; + keys = keyandchrs[1]; + dataoffset += chrs + 2; + + for (i = 0; i < parseInt(keys, 10); i++) { + kprops = _unserialize(data, dataoffset); + kchrs = kprops[1]; + key = kprops[2]; + dataoffset += kchrs; + + vprops = _unserialize(data, dataoffset); + vchrs = vprops[1]; + value = vprops[2]; + dataoffset += vchrs; + + readdata[key] = value; + } + + dataoffset += 1; + break; + case 'a': readdata = {}; keyandchrs = read_until(data, dataoffset, ':'); diff --git a/test/fixtures/serialized-data-5.txt b/test/fixtures/serialized-data-5.txt new file mode 100644 index 0000000..bf15177 --- /dev/null +++ b/test/fixtures/serialized-data-5.txt @@ -0,0 +1 @@ +O:8:'stdClass':0:{} diff --git a/test/fixtures/unserialized-data-5.json b/test/fixtures/unserialized-data-5.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/test/fixtures/unserialized-data-5.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/test/unserialize.js b/test/unserialize.js index 4fd3420..269936b 100644 --- a/test/unserialize.js +++ b/test/unserialize.js @@ -1,4 +1,3 @@ - var expect = require('chai').expect; var readFile = require('fs').readFile; var path = require('path'); @@ -6,33 +5,34 @@ var path = require('path'); var unserialize = require('..').unserialize; -function test_serialized_data (i) { - return function (done) { - var expected = require('./fixtures/unserialized-data-' + i + '.json'); - readFile(path.join(__dirname, 'fixtures', 'serialized-data-' + i + '.txt'), function (err, buffer) { - if (err) return done(err); - var unserialized = unserialize(buffer.toString()); - expect(unserialized).to.eql(expected); - done(); - }); - }; +function test_serialized_data(i) { + return function (done) { + var expected = require('./fixtures/unserialized-data-' + i + '.json'); + readFile(path.join(__dirname, 'fixtures', 'serialized-data-' + i + '.txt'), function (err, buffer) { + if (err) return done(err); + var unserialized = unserialize(buffer.toString()); + expect(unserialized).to.eql(expected); + done(); + }); + }; } -function test_serialized_error (i) { - return function (done) { - readFile(path.join(__dirname, 'fixtures', 'serialized-error-' + i + '.txt'), function (err, buffer) { - if (err) return done(err); - expect(unserialize.bind(this, buffer.toString())).to.throw(SyntaxError); - done(); - }); - }; +function test_serialized_error(i) { + return function (done) { + readFile(path.join(__dirname, 'fixtures', 'serialized-error-' + i + '.txt'), function (err, buffer) { + if (err) return done(err); + expect(unserialize.bind(this, buffer.toString())).to.throw(SyntaxError); + done(); + }); + }; } describe('unserialize()', function () { - it('should unserialize data sample #1', test_serialized_data(1)); - it('should unserialize data sample #2', test_serialized_data(2)); - it('should unserialize data sample #3', test_serialized_data(3)); - it('should unserialize data sample #4', test_serialized_data(4)); - it('should fail on erronous data sample #1', test_serialized_error(1)); - it('should fail on erronous data sample #2', test_serialized_error(1)); + it('should unserialize data sample #1', test_serialized_data(1)); + it('should unserialize data sample #2', test_serialized_data(2)); + it('should unserialize data sample #3', test_serialized_data(3)); + it('should unserialize data sample #4', test_serialized_data(4)); + it('should unserialize data sample #5', test_serialized_data(5)); + it('should fail on erronous data sample #1', test_serialized_error(1)); + it('should fail on erronous data sample #2', test_serialized_error(1)); });