Last active
August 22, 2016 02:11
-
-
Save Rodel30/c4a350c17467a45f2a3231facef87235 to your computer and use it in GitHub Desktop.
Basic attempt at a php deserializer in CFML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
component { | |
public any function run(required string data){ | |
variables.data = arguments.data; | |
variables.position = 1; | |
variables.bytebuffer = CreateObject("java", "java.nio.ByteBuffer"); | |
return deserializeItem(); | |
} | |
private any function deserializeItem(){ | |
// Don't use readUntil for this, because some types (like Null) use a different stop char | |
var type = Mid(variables.data, variables.position, 1); | |
variables.position += 2; //Skip over the : or ; after type | |
switch(type){ | |
case 'a': | |
var shell = {}; | |
var numKeys = readUntil(':'); | |
variables.position += 1; // Skip the opening { | |
var isArrayLike = true; | |
for( var i = 0; i < numKeys; i++ ){ | |
var key = deserializeItem(); | |
var value = deserializeItem(); | |
isArrayLike = isArrayLike && IsSimpleValue(key) && key == i; | |
shell[key] = value; | |
} | |
if( isArrayLike ){ | |
var arrShell = []; | |
for( var i = 0; i < numKeys; i++ ){ | |
arrShell.Append(shell[i]); | |
} | |
shell = arrShell; | |
} | |
variables.position += 1; // Skip over closing } | |
return shell; | |
break; | |
case 'b': | |
return !!Val(readUntil(';')); | |
break; | |
case 'd': | |
case 'i': | |
return readUntil(';'); | |
break; | |
case 'N': | |
return ''; // Or w/e you want to be "null" | |
break; | |
case 's': | |
var length = readUntil(':'); | |
var value = getString(length); | |
variables.position += 3 + Len(value); // Skip value, with enclosing quotes and the ; | |
return value; | |
break; | |
default: | |
throw( message = "Unknown Type: #type# Current position: #variables.position#", | |
detail = Mid(variables.data, variables.position - 20, 20)); | |
} | |
} | |
/* Gets a string value of a specific bytelength, doesn't alter position */ | |
private string function getString(required numeric length){ | |
var applicableString = Mid(variables.data, variables.position + 1, arguments.length); | |
var asbinary = charsetDecode( applicableString, "utf-8" ); | |
var buffer = variables.bytebuffer.Allocate( JavaCast( "int", arguments.length ) ); | |
buffer.Put( asbinary, JavaCast( "int", 0 ), JavaCast( "int", arguments.length ) ); | |
var binarySubString = buffer.Array(); | |
return charsetEncode( binarySubString, "utf-8" ); | |
} | |
/* Gets the value from current position to stop char, then sets the position to one after the stop char */ | |
private string function readUntil(required string stopChar){ | |
var stopCharPos = Find(arguments.stopChar, variables.data, variables.position); | |
var length = stopCharPos - variables.position; | |
var value = Mid(variables.data, variables.position, length); | |
variables.position = stopCharPos + 1; | |
return value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment