Skip to content

Commit bef6e6e

Browse files
committed
adding C and O parsing
1 parent 5fdbfd5 commit bef6e6e

File tree

3 files changed

+132
-36
lines changed

3 files changed

+132
-36
lines changed

php-unserialize.js

Lines changed: 122 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -121,58 +121,144 @@ function unserialize (data) {
121121
readdata = readData[1];
122122
dataoffset += chrs + 1;
123123
break;
124+
case 'c':
125+
var res = getClass(data, dataoffset);
126+
dataoffset = res[0];
127+
readdata = res[1];
128+
break;
129+
case 'o':
130+
var res = getObject(data, dataoffset);
131+
dataoffset = res[0];
132+
readdata = res[1];
133+
break;
124134
case 'n':
125135
readdata = null;
126136
break;
127137
case 's':
128-
ccount = read_until(data, dataoffset, ':');
129-
chrs = ccount[0];
130-
stringlength = ccount[1];
131-
dataoffset += chrs + 2;
132-
133-
readData = read_chrs(data, dataoffset + 1, parseInt(stringlength, 10));
134-
chrs = readData[0];
135-
readdata = readData[1];
136-
dataoffset += chrs + 2;
137-
if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
138-
error('SyntaxError', 'String length mismatch');
139-
}
138+
var res = getString(data, dataoffset);
139+
dataoffset = res[0];
140+
readdata = res[1];
140141
break;
141142
case 'a':
142-
readdata = {};
143-
144-
keyandchrs = read_until(data, dataoffset, ':');
145-
chrs = keyandchrs[0];
146-
keys = keyandchrs[1];
147-
dataoffset += chrs + 2;
148-
149-
for (i = 0; i < parseInt(keys, 10); i++) {
150-
kprops = _unserialize(data, dataoffset);
151-
kchrs = kprops[1];
152-
key = kprops[2];
153-
dataoffset += kchrs;
154-
155-
vprops = _unserialize(data, dataoffset);
156-
vchrs = vprops[1];
157-
value = vprops[2];
158-
dataoffset += vchrs;
159-
160-
readdata[key] = value;
161-
}
162-
163-
dataoffset += 1;
143+
var res = getArray(data, dataoffset);
144+
dataoffset = res[0];
145+
readdata = res[1];
164146
break;
165147
default:
166-
error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype);
148+
error('SyntaxError', 'Unknown / Unhandled data type(s): ' + dtype + ' :: ' + offset + JSON.stringify([dtype, data[offset], data.slice(offset-20, offset + 10), data]));
167149
break;
168150
}
169151
return [dtype, dataoffset - offset, typeconvert(readdata)];
170152
}
171153
;
172154

173-
return _unserialize((data + ''), 0)[2];
155+
function getArray(data, offset) {
156+
var readdata
157+
, chrs
158+
, keys
159+
, dataoffset = offset
160+
, kprops
161+
, kchrs
162+
, key
163+
, vprops
164+
, vchrs
165+
, keyandchrs
166+
, i
167+
, value;
168+
readdata = {};
169+
170+
keyandchrs = read_until(data, dataoffset, ':');
171+
chrs = keyandchrs[0];
172+
keys = keyandchrs[1];
173+
dataoffset += chrs + 2;
174+
175+
for (i = 0; i < parseInt(keys, 10); i++) {
176+
kprops = _unserialize(data, dataoffset);
177+
kchrs = kprops[1];
178+
key = kprops[2];
179+
dataoffset += kchrs;
180+
181+
vprops = _unserialize(data, dataoffset);
182+
vchrs = vprops[1];
183+
value = vprops[2];
184+
dataoffset += vchrs;
185+
186+
readdata[key] = value;
187+
}
188+
189+
dataoffset += 1;
190+
return [dataoffset, readdata];
174191
}
175192

193+
function getCount(data, offset) {
194+
var ccount
195+
, count
196+
, chrs
197+
, stringlength
198+
, readData
199+
, readdata;
200+
ccount = read_until(data, offset, ':');
201+
chrs = ccount[0];
202+
count = ccount[1];
203+
offset += chrs + 2;
204+
return [offset, count];
205+
};
206+
207+
function getObject(data, offset) {
208+
var res = getString(data, offset)
209+
, body
210+
, classname = res[1];
211+
212+
offset = res[0];
213+
res = getArray(data, offset);
214+
offset = res[0];
215+
return [offset, {name: classname, body: res[1]}];
216+
};
217+
218+
219+
function getClass(data, offset) {
220+
var res = getString(data, offset)
221+
, body
222+
, classname = res[1];
223+
224+
offset = res[0];
225+
res = getCount(data, offset);
226+
offset = res[0];
227+
body = data.slice(offset - 1, offset + parseInt(res[1]) );
228+
if (body[0] !== '{' || body[body.length - 1] !== '}') {
229+
throw new Error('invalid body defn: ' + JSON.stringify([body, offset, res[1], data.slice(offset-1, offset+10)]));
230+
}
231+
body = body.slice(1, -1);
232+
try {
233+
body = _unserialize(body, 0)[2];
234+
} catch (e) {
235+
}
236+
return [offset + parseInt(res[1]) + 1, {name: classname, body: body}];
237+
};
238+
239+
function getString(data, offset) {
240+
var ccount
241+
, chrs
242+
, stringlength
243+
, readData
244+
, readdata;
245+
ccount = read_until(data, offset, ':');
246+
chrs = ccount[0];
247+
stringlength = ccount[1];
248+
offset += chrs + 2;
249+
250+
readData = read_chrs(data, offset + 1, parseInt(stringlength, 10));
251+
chrs = readData[0];
252+
readdata = readData[1];
253+
offset += chrs + 2;
254+
if (chrs != parseInt(stringlength, 10) && chrs != readdata.length) {
255+
error('SyntaxError', 'String length mismatch');
256+
}
257+
return [offset, readdata];
258+
};
259+
260+
return _unserialize((data + ''), 0)[2];
261+
}
176262
/**
177263
* Parse PHP-serialized session data
178264
*

test/session.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,13 @@ describe('unserializeSession()', function () {
1616
done();
1717
});
1818
});
19+
it('should unserialize data sample 2', function (done) {
20+
var expected = require('./fixtures/unserialized-session-2.json');
21+
readFile(path.join(__dirname, 'fixtures', 'serialized-session-2.txt'), function (err, buffer) {
22+
if (err) return done(err);
23+
var unserialized = unserialize(buffer.toString());
24+
expect(unserialized).to.eql(expected);
25+
done();
26+
});
27+
});
1928
});

test/unserialize.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ describe('unserialize()', function () {
3333
it('should unserialize data sample #2', test_serialized_data(2));
3434
it('should unserialize data sample #3', test_serialized_data(3));
3535
it('should unserialize data sample #4', test_serialized_data(4));
36+
it('should unserialize data sample #5', test_serialized_data(5));
3637
it('should fail on erronous data sample #1', test_serialized_error(1));
3738
it('should fail on erronous data sample #2', test_serialized_error(1));
3839
});

0 commit comments

Comments
 (0)