made pbkdf2 funuctional in python 3

started refactoring other code to work in python 3

--HG--
branch : mung
This commit is contained in:
cecilkorik 2019-04-23 16:29:46 -07:00
parent 0b3c747e93
commit 25db8c81e0
8 changed files with 233 additions and 219 deletions

View file

@ -1,2 +1,5 @@
syntax: glob syntax: glob
*.pyc *.pyc
bin
lib
include

View file

@ -1,4 +1,4 @@
from builtins_code import bi from bi_code import bi
__all__ = ['builtin_map'] __all__ = ['builtin_map']
@ -113,4 +113,4 @@ listbi_map.update({
'len': bi.list_len, 'len': bi.list_len,
'sort': bi.list_sort, 'sort': bi.list_sort,
}) })
""" """

View file

@ -1,5 +1,5 @@
from language_tools import * from language_tools import *
from builtins import builtin_map from bi import builtin_map
import optimizer import optimizer
@ -11,7 +11,7 @@ def coerce(value):
return VMInteger(value) return VMInteger(value)
elif isinstance(value, (tuple, list)): elif isinstance(value, (tuple, list)):
return VMList(list(value)) return VMList(list(value))
elif isinstance(value, unicode): elif isinstance(value, str):
return VMString(value) return VMString(value)
elif isinstance(value, dict): elif isinstance(value, dict):
return VMTable(value) return VMTable(value)
@ -298,7 +298,7 @@ class UnaryOp(CodeOp):
rv = [] rv = []
ops = [] ops = []
for t in tokens: for t in tokens:
if isinstance(t, (str, unicode)) and t in UnaryOp.map: if isinstance(t, (str, bytes)) and t in UnaryOp.map:
ops.append(UnaryOp(UnaryOp.map[t])) ops.append(UnaryOp(UnaryOp.map[t]))
else: else:
rv.append(t) rv.append(t)
@ -524,7 +524,7 @@ class WhileBlock(CodeOp):
def parse(tokens): def parse(tokens):
rv = WhileBlock() rv = WhileBlock()
for i in xrange(1, len(tokens)): for i in range(1, len(tokens)):
tok = tokens[i] tok = tokens[i]
if rv.cond == None: if rv.cond == None:
rv.cond = tok rv.cond = tok
@ -583,7 +583,7 @@ class TryBlock(CodeOp):
rv = TryBlock() rv = TryBlock()
active_tok = None active_tok = None
for i in xrange(1, len(tokens)): for i in range(1, len(tokens)):
tok = tokens[i] tok = tokens[i]
if tok in ("try", "except", "else", "finally"): if tok in ("try", "except", "else", "finally"):
active_tok = tok active_tok = tok
@ -677,7 +677,7 @@ class ForeachBlock(CodeOp):
def parse(tokens): def parse(tokens):
rv = ForeachBlock() rv = ForeachBlock()
for i in xrange(1, len(tokens)): for i in range(1, len(tokens)):
tok = tokens[i] tok = tokens[i]
if rv.var == None: if rv.var == None:
rv.var = tok rv.var = tok
@ -717,7 +717,7 @@ class IfBlock(CodeOp):
conds = [] conds = []
tok_count = 0 tok_count = 0
active_tok = None active_tok = None
for i in xrange(len(tokens)): for i in range(len(tokens)):
tok = tokens[i] tok = tokens[i]
if tok == "endif": if tok == "endif":

View file

@ -12,7 +12,7 @@ def disallow_keywords(tokens,keywords=None):
if isinstance(t, VMIdent): if isinstance(t, VMIdent):
if t.name in keywords: if t.name in keywords:
raise ParseException("Restricted keyword: %s" % (t.name,)) raise ParseException("Restricted keyword: %s" % (t.name,))
elif isinstance(t, unicode): elif isinstance(t, str):
tstr = t.encode('ascii', 'ignore') tstr = t.encode('ascii', 'ignore')
if tstr in keywords: if tstr in keywords:
raise ParseException("Restricted keyword: %s" % (tstr,)) raise ParseException("Restricted keyword: %s" % (tstr,))
@ -98,10 +98,10 @@ class VMTablePair(VMType):
class VMString(VMType): class VMString(VMType):
def __init__(self, value): def __init__(self, value):
VMType.__init__(self) VMType.__init__(self)
if isinstance(value, unicode): if isinstance(value, str):
self.value = value self.value = value
else: else:
self.value = unicode(str(value), 'ascii', 'ignore') self.value = str(value, 'ascii', 'ignore')
def __repr__(self): def __repr__(self):
return "\"%s\"" % (repr(self.value)[1:].strip("'").replace("\\'", "'").replace('"', '\\"'),) return "\"%s\"" % (repr(self.value)[1:].strip("'").replace("\\'", "'").replace('"', '\\"'),)
@ -138,7 +138,7 @@ class VMIdent(VMRef):
self.name = name self.name = name
def bytecode(self): def bytecode(self):
return [StackLiteral(unicode(self.name))] return [StackLiteral(str(self.name))]
@staticmethod @staticmethod
@tokenparser @tokenparser
@ -156,7 +156,7 @@ class VMVariable(VMRef):
self.name = name self.name = name
def ref(self): def ref(self):
return [StackLiteral(unicode(self.name))] return [StackLiteral(str(self.name))]
def bytecode(self): def bytecode(self):
return codejoin(self.ref(), GetVariable()) return codejoin(self.ref(), GetVariable())

View file

@ -92,12 +92,12 @@ class Connection(object):
data = self.conn.recv(bytes) data = self.conn.recv(bytes)
if self.input_encoding == 'raw': if self.input_encoding == 'raw':
return unicode(self.escape(data), 'ascii') return str(self.escape(data), 'ascii')
else: else:
return unicode(data, self.input_encoding, 'ignore') return str(data, self.input_encoding, 'ignore')
def send(self, data): def send(self, data):
assert isinstance(data, unicode) assert isinstance(data, str)
try: try:
encoded = data.encode(self.output_encoding, 'replace') encoded = data.encode(self.output_encoding, 'replace')
except UnicodeEncodeError: except UnicodeEncodeError:

393
parse.py
View file

@ -3,208 +3,215 @@ from language import *
class Parser(object): class Parser(object):
def __init__(self): def __init__(self):
self.parser = None self.parser = None
self.init_parser() self.init_parser()
def nest(self, tokens): def nest(self, tokens):
return [list(tokens)] return [list(tokens)]
def init_parser(self): def init_parser(self):
""" phase 1: """ phase 1:
most important part is to build the meta-parser for "expr". expr represents any atomic action that returns a value, and the bulk of most important part is to build the meta-parser for "expr". expr represents any atomic action that returns a value, and the bulk of
the code in any program will consist primarily of exprs and flow control. expr is heavily recursive, because most types of expr can the code in any program will consist primarily of exprs and flow control. expr is heavily recursive, because most types of expr can
take another expr as an input value. take another expr as an input value.
""" """
point = Literal( "." ) point = Literal( "." )
plus = Literal( "+" ) plus = Literal( "+" )
minus = Literal( "-" ) minus = Literal( "-" )
mult = Literal( "*" ) mult = Literal( "*" )
div = Literal( "/" ) div = Literal( "/" )
lpar = Literal( "(" ).suppress() lpar = Literal( "(" ).suppress()
rpar = Literal( ")" ).suppress() rpar = Literal( ")" ).suppress()
llbr = Literal( "[" ).suppress() llbr = Literal( "[" ).suppress()
rlbr = Literal( "]" ).suppress() rlbr = Literal( "]" ).suppress()
addop = plus | minus addop = plus | minus
multop = mult | div multop = mult | div
expop = Literal( "^" ) expop = Literal( "^" )
quote = Literal( '"' ) quote = Literal( '"' )
excl = Literal( "!" ) excl = Literal( "!" )
call = Literal( ":" ) call = Literal( ":" )
endl = Literal( ";" ) endl = Literal( ";" )
lisep = Literal( "," ).suppress() lisep = Literal( "," ).suppress()
objn = Literal( "#" ) objn = Literal( "#" )
ref = Literal( "$" ) ref = Literal( "$" )
assign = Literal( "=" ) assign = Literal( "=" )
flatten = Literal( "@" ) flatten = Literal( "@" )
neg = excl.copy() neg = excl.copy()
expr = Forward() expr = Forward()
ident = Word(alphas+"_", alphas+nums+"_") ident = Word(alphas+"_", alphas+nums+"_")
ident.setParseAction(VMIdent.parse) ident.setParseAction(VMIdent.parse)
variable = Word(alphas+"_", alphas+nums+"_") variable = Word(alphas+"_", alphas+nums+"_")
variable.setParseAction(VMVariable.parse) variable.setParseAction(VMVariable.parse)
integer = Word( "+-"+nums, nums ) integer = Word( "+-"+nums, nums )
fnumber = Combine( integer + fnumber = Combine( integer +
Optional( point + Optional( Word( nums ) ) ) + Optional( point + Optional( Word( nums ) ) ) +
Optional( CaselessLiteral('e') + Word( "+-"+nums, nums ) ) ) Optional( CaselessLiteral('e') + Word( "+-"+nums, nums ) ) )
objref = objn + Word( "+-"+nums, nums ) objref = objn + Word( "+-"+nums, nums )
objref.setParseAction(VMObjRef.parse) objref.setParseAction(VMObjRef.parse)
coreref = (ref + ident) coreref = (ref + ident)
coreref.setParseAction(VMCoreRef.parse) coreref.setParseAction(VMCoreRef.parse)
bexpr = (lpar + expr + rpar).setParseAction(self.nest) bexpr = (lpar + expr + rpar).setParseAction(self.nest)
objrefexpr = bexpr | coreref | variable | objref objrefexpr = bexpr | coreref | variable | objref
identexpr = bexpr | ident identexpr = bexpr | ident
propref = (objrefexpr + point + ident).setParseAction(VMPropRef.parse) | coreref propref = (objrefexpr + point + ident).setParseAction(VMPropRef.parse) | coreref
fileref = (objrefexpr + excl + ident).setParseAction(VMFileRef.parse) fileref = (objrefexpr + excl + ident).setParseAction(VMFileRef.parse)
argspec = Optional(delimitedList(expr)) argspec = Optional(delimitedList(expr))
argspec.setParseAction(StackToList.parse) argspec.setParseAction(StackToList.parse)
funccall = objrefexpr + call + identexpr + lpar + argspec + rpar funccall = objrefexpr + call + identexpr + lpar + argspec + rpar
fnumber.setParseAction(VMFloat.parse) fnumber.setParseAction(VMFloat.parse)
integer.setParseAction(VMInteger.parse) integer.setParseAction(VMInteger.parse)
funccall.setParseAction(CallFunc.parse) funccall.setParseAction(CallFunc.parse)
stringlit = QuotedString(quoteChar='"', escChar='\\').setParseAction(VMString.parse) stringlit = QuotedString(quoteChar='"', escChar='\\').setParseAction(VMString.parse)
atom = Forward() atom = Forward()
bifunction = (ident + lpar + argspec + rpar).setParseAction(CallBuiltin.parse) bifunction = (ident + lpar + argspec + rpar).setParseAction(CallBuiltin.parse)
flatexpr = Optional(flatten) + expr flatexpr = Optional(flatten) + expr
flatexpr.setParseAction(Flatten.parse) flatexpr.setParseAction(Flatten.parse)
listlit = llbr + Optional(flatexpr) + ZeroOrMore(lisep + flatexpr) + rlbr listlit = llbr + Optional(flatexpr) + ZeroOrMore(lisep + flatexpr) + rlbr
literal = integer | fnumber | stringlit | listlit | objref literal = integer | fnumber | stringlit | listlit | objref
atom << (Optional(minus) + ZeroOrMore(neg) + (propref | literal | bifunction | bexpr | variable | funccall | fileref)).setParseAction(UnaryOp.parse) atom << (Optional(minus) + ZeroOrMore(neg) + (propref | literal | bifunction | bexpr | variable | funccall | fileref)).setParseAction(UnaryOp.parse)
atom = atom.streamline()
# by defining exponentiation as "atom [ ^ factor ]..." instead of "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-righ
# that is, 2^3^2 = 2^(3^2), not (2^3)^2. # by defining exponentiation as "atom [ ^ factor ]..." instead of "atom [ ^ atom ]...", we get right-to-left exponents, instead of left-to-righ
factor = Forward() # that is, 2^3^2 = 2^(3^2), not (2^3)^2.
factor << atom + ZeroOrMore( (expop + factor).setParseAction(ArithExp.parse) ) factor = Forward()
factor << atom + ZeroOrMore( (expop + factor).setParseAction(ArithExp.parse) )
term = factor + ZeroOrMore( (multop + factor).setParseAction(ArithMul.parse) ) factor = factor.streamline()
#term.setParseAction(self.nest)
mathexpr = term + ZeroOrMore( (addop + term).setParseAction(ArithAdd.parse) ) term = factor + ZeroOrMore( (multop + factor).setParseAction(ArithMul.parse) )
#mathexpr.setParseAction(self.nest) #term.setParseAction(self.nest)
mathexpr = term + ZeroOrMore( (addop + term).setParseAction(ArithAdd.parse) )
opeq = Literal('==') #mathexpr.setParseAction(self.nest)
opneq = Literal('!=')
opgteq = Literal('<=') opeq = Literal('==')
oplteq = Literal('>=') opneq = Literal('!=')
oplt = Literal('<') opgteq = Literal('<=')
opgt = Literal('>') oplteq = Literal('>=')
opin = Keyword('in') oplt = Literal('<')
opgt = Literal('>')
opcmp = opeq | opneq | opgteq | oplteq | oplt | opgt | opin opin = Keyword('in')
eqexpr = mathexpr + Optional( (opcmp + mathexpr).setParseAction(BoolCompare.parse) )
opcmp = opeq | opneq | opgteq | oplteq | oplt | opgt | opin
opand = Literal('&&') | Keyword('and') eqexpr = mathexpr + Optional( (opcmp + mathexpr).setParseAction(BoolCompare.parse) )
opor = Literal('||') | Keyword('or')
opxor = Literal('~~') | Keyword('xor') opand = Literal('&&') | Keyword('and')
opor = Literal('||') | Keyword('or')
opbool = opand | opor | opxor opxor = Literal('~~') | Keyword('xor')
boolexpr = eqexpr + ZeroOrMore( (opbool + eqexpr).setParseAction(BoolLogic.parse) )
opbool = opand | opor | opxor
boolexpr = eqexpr + ZeroOrMore( (opbool + eqexpr).setParseAction(BoolLogic.parse) )
assignable = variable | propref | fileref
assignexpr = Optional(assignable + assign) + boolexpr
expr << assignexpr.setParseAction(Assignment.parse) assignable = variable | propref | fileref
assignexpr = Optional(assignable + assign) + boolexpr
expr << assignexpr.setParseAction(Assignment.parse)
""" phase 2: expr = expr.streamline()
now that expr is built, we can move on to handling flow control statements, and after that the structure of the program
is mostly defined
"""
ifstart = (Keyword("if") + bexpr)
ifelseif = (Keyword("elseif") + bexpr)
ifelse = Keyword("else")
ifend = Keyword("endif")
trystart = Keyword("try")
tryexcept = (Keyword("except") + variable)
tryelse = Keyword("else")
tryfinally = Keyword("finally")
tryend = Keyword("endtry")
whilestart = (Keyword("while") + bexpr)
whileend = Keyword("endwhile")
forstart = (Keyword("for") + variable + Keyword("in") + bexpr)
forend = Keyword("endfor")
kwdbreak = Keyword("break").setParseAction(LoopBreak)
kwdcontinue = Keyword("continue").setParseAction(LoopContinue)
kwdreturn = Keyword("return") """ phase 2:
now that expr is built, we can move on to handling flow control statements, and after that the structure of the program
is mostly defined
"""
ifstart = (Keyword("if") + bexpr)
ifelseif = (Keyword("elseif") + bexpr)
ifelse = Keyword("else")
ifend = Keyword("endif")
trystart = Keyword("try")
tryexcept = (Keyword("except") + variable)
tryelse = Keyword("else")
tryfinally = Keyword("finally")
tryend = Keyword("endtry")
whilestart = (Keyword("while") + bexpr)
whileend = Keyword("endwhile")
forstart = (Keyword("for") + variable + Keyword("in") + bexpr)
forend = Keyword("endfor")
rtnexpr = (kwdreturn + expr).setParseAction(KeywordReturn.parse) kwdbreak = Keyword("break").setParseAction(LoopBreak)
line = expr | rtnexpr kwdcontinue = Keyword("continue").setParseAction(LoopContinue)
lline = expr | rtnexpr | kwdcontinue | kwdbreak kwdreturn = Keyword("return")
exprblock = ZeroOrMore(line + endl)
lexprblock = ZeroOrMore(lline + endl)
block = Forward() rtnexpr = (kwdreturn + expr).setParseAction(KeywordReturn.parse)
lblock = Forward() line = expr | rtnexpr
ifblock = ifstart + block + ZeroOrMore(ifelseif + block) + Optional(ifelse + block) + ifend lline = expr | rtnexpr | kwdcontinue | kwdbreak
tryblock = trystart + block + Optional(tryexcept + block + Optional(tryelse + block)) + Optional(tryfinally + block) + tryend exprblock = ZeroOrMore(line + endl)
iflblock = ifstart + lblock + ZeroOrMore(ifelseif + lblock) + Optional(ifelse + lblock) + ifend lexprblock = ZeroOrMore(lline + endl)
trylblock = trystart + lblock + Optional(tryexcept + lblock + Optional(tryelse + lblock)) + Optional(tryfinally + block) + tryend
whileblock = whilestart + lblock + whileend
forblock = forstart + lblock + forend
ifblock.setParseAction(IfBlock.parse)
tryblock.setParseAction(TryBlock.parse)
iflblock.setParseAction(IfBlock.parse)
trylblock.setParseAction(TryBlock.parse)
whileblock.setParseAction(WhileBlock.parse)
forblock.setParseAction(ForeachBlock.parse)
# blocks are used for code blocks that are outside a loop. Inside a loop, all code blocks are lblocks
# which allow loop-control keywords like break and continue (except try-finally, it wouldn't make sense)
block << (exprblock + Optional(ifblock | tryblock | whileblock | forblock) + exprblock)
lblock << (lexprblock + Optional(iflblock | trylblock | whileblock | forblock) + lexprblock)
block.setParseAction(self.nest)
lblock.setParseAction(self.nest)
endl.setParseAction(DiscardStack.parse) block = Forward()
self.parser = block lblock = Forward()
#print(argspec.parseString("hello(hi.xyz)", parseAll=True)) ifblock = ifstart + block + ZeroOrMore(ifelseif + block) + Optional(ifelse + block) + ifend
#print(block.parseString(u"hi.xyz + #555.test;", parseAll=True)) tryblock = trystart + block + Optional(tryexcept + block + Optional(tryelse + block)) + Optional(tryfinally + block) + tryend
#print(block.parseString("""serverlog();""")) iflblock = ifstart + lblock + ZeroOrMore(ifelseif + lblock) + Optional(ifelse + lblock) + ifend
trylblock = trystart + lblock + Optional(tryexcept + lblock + Optional(tryelse + lblock)) + Optional(tryfinally + block) + tryend
whileblock = whilestart + lblock + whileend
forblock = forstart + lblock + forend
ifblock.setParseAction(IfBlock.parse)
tryblock.setParseAction(TryBlock.parse)
iflblock.setParseAction(IfBlock.parse)
trylblock.setParseAction(TryBlock.parse)
whileblock.setParseAction(WhileBlock.parse)
forblock.setParseAction(ForeachBlock.parse)
# blocks are used for code blocks that are outside a loop. Inside a loop, all code blocks are lblocks
# which allow loop-control keywords like break and continue (except try-finally, it wouldn't make sense)
block << (exprblock + Optional(ifblock | tryblock | whileblock | forblock) + exprblock)
lblock << (lexprblock + Optional(iflblock | trylblock | whileblock | forblock) + lexprblock)
def parse(self, data): block = block.streamline()
rv = self.parser.parseString(data, parseAll=True) lblock = lblock.streamline()
return optimizer.optimize(rv) block.setParseAction(self.nest)
lblock.setParseAction(self.nest)
def parse_command(self, line): endl.setParseAction(DiscardStack.parse)
ls = line.split(' ') self.parser = block
cmd = ls[0] #print(argspec.parseString("hello(hi.xyz)", parseAll=True))
argstr = ' '.join(ls[1:]) #print(block.parseString(u"hi.xyz + #555.test;", parseAll=True))
vars = { #print(block.parseString("""serverlog();"""))
'cmdstr': line,
'cmd': cmd,
'argstr': argstr,
'args': [x.strip() for x in ls[1:] if x.strip() != '']
}
return [cmd, vars]
def test(self): def parse(self, data):
#print(self.parse(u"if (1) #740.xyz + -hello.world; endif")) rv = self.parser.parseString(data, parseAll=True)
data = unicode(open("test.moo", "r").read(), 'utf-8') return optimizer.optimize(rv)
rv = self.parse(data)
print(rv) def parse_command(self, line):
return rv ls = line.split(' ')
cmd = ls[0]
argstr = ' '.join(ls[1:])
vars = {
'cmdstr': line,
'cmd': cmd,
'argstr': argstr,
'args': [x.strip() for x in ls[1:] if x.strip() != '']
}
return [cmd, vars]
def test(self):
#print(self.parse(u"if (1) #740.xyz + -hello.world; endif"))
data = open("test.moo", "r", encoding="utf-8").read()
rv = self.parse(data)
print(rv)
return rv
static_parser = Parser() static_parser = Parser()
if __name__ == "__main__": if __name__ == "__main__":
p = Parser() p = Parser()
p.test() p.test()

View file

@ -44,7 +44,8 @@ import hmac
import hashlib import hashlib
from struct import Struct from struct import Struct
from operator import xor from operator import xor
from itertools import izip, starmap from itertools import starmap
import binascii
_pack_int = Struct('>I').pack _pack_int = Struct('>I').pack
@ -52,7 +53,7 @@ _pack_int = Struct('>I').pack
def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Like :func:`pbkdf2_bin` but returns a hex encoded string.""" """Like :func:`pbkdf2_bin` but returns a hex encoded string."""
return pbkdf2_bin(data, salt, iterations, keylen, hashfunc).encode('hex') return str(binascii.hexlify(pbkdf2_bin(data, salt, iterations, keylen, hashfunc)), 'ascii')
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
@ -61,26 +62,29 @@ def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
key of `keylen` bytes. By default SHA-256 is used as hash function, key of `keylen` bytes. By default SHA-256 is used as hash function,
a different hashlib `hashfunc` can be provided. a different hashlib `hashfunc` can be provided.
""" """
bchr = lambda v: bytes((v,))
hashfunc = hashfunc or hashlib.sha256 hashfunc = hashfunc or hashlib.sha256
mac = hmac.new(data, None, hashfunc) mac = hmac.new(data, None, hashfunc)
def _pseudorandom(x, mac=mac): def _pseudorandom(x, mac=mac):
h = mac.copy() h = mac.copy()
h.update(x) h.update(x)
return map(ord, h.digest()) return h.digest()
buf = [] buf = []
for block in xrange(1, -(-keylen // mac.digest_size) + 1): for block in range(1, -(-keylen // mac.digest_size) + 1):
rv = u = _pseudorandom(salt + _pack_int(block)) rv = u = _pseudorandom(salt + _pack_int(block))
for i in xrange(iterations - 1): for i in range(iterations - 1):
u = _pseudorandom(''.join(map(chr, u))) u = _pseudorandom(b''.join(map(bchr, u)))
rv = starmap(xor, izip(rv, u)) rv = starmap(xor, zip(rv, u))
buf.extend(rv) buf.extend(rv)
return ''.join(map(chr, buf))[:keylen] return b''.join(map(bchr, buf))[:keylen]
def test(): def test():
failed = [] failed = []
def check(data, salt, iterations, keylen, expected): def check(data, salt, iterations, keylen, expected):
rv = pbkdf2_hex(data, salt, iterations, keylen) rv = pbkdf2_hex(bytes(data, "utf-8"), bytes(salt, "utf-8"), iterations, keylen, hashlib.sha1)
if rv != expected: if rv != expected:
print('Test failed:') print('Test failed:')
print(' Expected: %s' % expected) print(' Expected: %s' % expected)