Add PHP Deserialization.

This commit is contained in:
Jarmo van Lenthe 2017-11-12 21:37:29 -05:00
parent 2cd4256ece
commit 4be7f89fd8
4 changed files with 145 additions and 1 deletions

View File

@ -66,6 +66,7 @@ const Categories = [
"Encode text",
"Decode text",
"Swap endianness",
"PHP Deserialize",
]
},
{

View File

@ -35,6 +35,7 @@ import StrUtils from "../operations/StrUtils.js";
import Tidy from "../operations/Tidy.js";
import Unicode from "../operations/Unicode.js";
import URL_ from "../operations/URL.js";
import PhpSerialization from "../operations/PhpSerialization.js";
/**
@ -3845,6 +3846,19 @@ const OperationConfig = {
}
]
},
"PHP Deserialize": {
module: "Default",
description: "PHP Deserialize a given input.<br><br>This function does not support <code>object</code> tags.<br><br><u>Output valid JSON:</u> JSON doesn't support integers as keys, where as PHP serialization does. Enabling this will cast these integers to strings. This will also escape backslashes.",
inputType: "string",
outputType: "string",
args: [
{
name: "Output valid JSON",
type: "boolean",
value: PhpSerialization.OUTPUT_VALID_JSON
}
]
},
};

View File

@ -27,7 +27,7 @@ import StrUtils from "../../operations/StrUtils.js";
import Tidy from "../../operations/Tidy.js";
import Unicode from "../../operations/Unicode.js";
import UUID from "../../operations/UUID.js";
import PhpSerialization from "../../operations/PhpSerialization";
/**
* Default module.
@ -155,6 +155,7 @@ OpModules.Default = {
"Conditional Jump": FlowControl.runCondJump,
"Return": FlowControl.runReturn,
"Comment": FlowControl.runComment,
"PHP Deserialize": PhpSerialization.PhpDeserialize,
/*

View File

@ -0,0 +1,128 @@
/**
* Php Serialization operations.
* This Javascript implementation is based on the Python
* implementation by Armin Ronacher (2016).
* See: https://github.com/mitsuhiko/phpserialize/
*
* @author Jarmo van Lenthe [github.com/jarmovanlenthe]
* @copyright Crown Copyright 2017
* @license BSD-3-Clause
*
* @namespace
*/
const PhpSerialization = {
/**
* @constant
* @default
*/
OUTPUT_VALID_JSON: true,
PhpDeserialize: function (input, args) {
function handleInput() {
function read(length) {
let result = "";
for (let idx = 0; idx < length; idx++) {
let char = inputPart.shift();
if (char === undefined) {
throw "End of input reached before end of script";
}
result += char;
}
return result;
}
function readUntil(until) {
let result = "";
while (true) {
let char = read(1);
if (char === until) {
break;
}
else {
result += char;
}
}
return result;
}
function expect(expect) {
let result = read(expect.length);
if (result !== expect) {
throw "Unexpected input found";
}
return result;
}
function handleArray() {
let items = parseInt(readUntil(':')) * 2;
expect('{');
let result = [];
let isKey = true;
let last_item = null;
for (let idx = 0; idx < items; idx++) {
let item = handleInput();
if (isKey) {
last_item = item;
isKey = false;
} else {
let numberCheck = last_item.match(/[0-9]+/);
if (args[0] && numberCheck && numberCheck[0].length === last_item.length)
{
result.push('"' + last_item + '": ' + item);
} else {
result.push(last_item + ': ' + item);
}
isKey = true;
}
}
expect('}');
return result;
}
let kind = read(1).toLowerCase();
switch (kind) {
case 'n':
expect(';');
return '';
case 'i':
case 'd':
case 'b':
expect(':');
let data = readUntil(';');
if (kind === 'b')
return (parseInt(data) !== 0);
return data;
case 'a':
expect(':');
return '{' + handleArray() + '}';
case 's':
expect(':');
let length = readUntil(':');
expect('"');
let value = read(length);
expect('";');
if (args[0])
return '"' + value.replace(/"/g, '\\"') + '"';
else
return '"' + value + '"';
default:
throw "Unknown type: " + kind;
}
}
let inputPart = input.split('');
return handleInput();
}
};
export default PhpSerialization;