1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
"""
MoinMoin - Parsing of PHP session files
@copyright: 2005 MoinMoin:AlexanderSchremmer (Thanks to Spreadshirt)
@license: GNU GPL, see COPYING for details.
"""
#Known minor bugs/questions/ideas:
#How does object demarshalling work?
#The order of the python dictionaries is not stable compared to the PHP arrays
#The loader does not check the owner of the files, so be aware of faked session
#files.
import os
from MoinMoin import wikiutil
s_prefix = "sess_"
s_path = "/tmp"
class UnknownObject(object):
""" Used in the return value if the input data could not be parsed. """
def __init__(self, pos):
self.pos = pos
def __repr__(self):
return "<Unknown object at pos %i>" % self.pos
def transformList(items):
""" Transforms a list [1, 2, 3, 4, ...] into a
[(1, 2), (3, 4), ...] generator. """
for i in xrange(0, len(items), 2):
yield (items[i], items[i+1])
raise StopIteration
def parseValue(string, start=0):
""" Parses the inner structure. """
# TODO: replace "string" by something else
#print "Parsing %r" % (string[start:], )
val_type = string[start]
try:
header_end = string.index(':', 3+start)
first_data = string[start+2:header_end]
except ValueError:
first_data = None
#print "Saw type %r, first_data is %r." % (val_type, first_data)
if val_type == 'a': # array (in Python rather a mixture of a list and a dict)
i = 0
items = []
current_pos = header_end+2
data = string
while i != (int(first_data) * 2):
item, current_pos = parseValue(data, current_pos)
items.append(item)
i += 1
current_pos += 1
t_list = list(transformList(items))
try:
result = dict(t_list) # note that dict does not retain the order
except TypeError:
result = list(t_list)
#print "Warning, could not convert to dict: %r" % (result, )
return result, current_pos
if val_type == 's': # string
current_pos = header_end+2
end = current_pos + int(first_data)
data = string[current_pos:end]
current_pos = end+1
if data.startswith("a:"): #Sometimes, arrays are marshalled as strings.
try:
data = parseValue(data, 0)[0]
except ValueError: #Hmm, wrongly guessed. Just an ordinary string
pass
return data, current_pos
if val_type in ('i', 'b'): # integer or boolean
current_pos = start+2
str_buffer = ""
while current_pos != len(string):
cur_char = string[current_pos]
if cur_char.isdigit() or cur_char == "-":
str_buffer += cur_char
else:
cast = (val_type == 'i') and int or (lambda x: bool(int(x)))
return cast(str_buffer), current_pos
current_pos += 1
if val_type == "N": # Null, called None in Python
return None, start+1
return UnknownObject(start), start+1
def parseSession(boxed):
""" Parses the outer structure that is similar to a dict. """
current_pos = 0
session_dict = {}
while current_pos < len(boxed):
name_end = boxed.find("|", current_pos) # TODO: replace by .index()?
name = boxed[current_pos:name_end]
current_pos = name_end+1
data, current_pos = parseValue(boxed, current_pos)
current_pos += 1
session_dict[name] = data
return session_dict
def loadSession(key, path=s_path, prefix=s_prefix):
""" Loads a particular session from the directory. The key needs to be the
session id. """
key = key.lower()
filename = os.path.join(path, prefix + wikiutil.taintfilename(key))
try:
f = open(filename, "rb")
except IOError, e:
if e.errno == 2:
return None # session does not exist
else:
raise
blob = f.read()
f.close()
return parseSession(blob)
def listSessions(path=s_path, prefix=s_prefix):
""" Lists all sessions in a particular directory. """
return [os.path.basename(x).replace(s_prefix, '') for x in os.listdir(s_path)
if x.startswith(s_prefix)]
if __name__ == '__main__':
# testing code
import time
a = time.clock()
#print s
p_s = loadSession("...")
import pprint
pprint.pprint(p_s)
print time.clock() - a
print listSessions()
|