Variables should not contain & since that can execute arbitrary code on UNIX
[pyvconv.git] / pyvconv.py
blobc7a816e804654351212278a5fea4470cf82eb09a
1 import libxml2
2 import re
4 class RenderCommand:
5 def __init__(self, name_str, cmd_str, optset_list):
6 self.name_str = name_str
7 self.cmd_str = cmd_str
9 self.var_list = {}
10 self.var_list["in"] = None
11 self.var_list["out"] = None
12 self.var_list["quality"] = None
14 self.optset_list = optset_list
16 def set_var(self, var_str, val_str):
17 if val_str.find("&") != -1:
18 raise "Warning: Trying to execute arbitrary code"
19 self.var_list[var_str] = val_str
21 def _insert_known_vars(self, instr):
22 for var in self.var_list:
23 if self.var_list[var] != None:
24 p = re.compile( '\$\{' + var + '\}')
25 instr = p.sub( self.var_list[var], instr)
26 return instr
28 def _contains_vars(self, instr):
29 if instr.find("$") != -1:
30 return True
31 else:
32 return False
34 def execute(self):
35 cmd_to_run = self.cmd_str
37 # insert all known variables in cmd string
38 cmd_to_run = self._insert_known_vars(cmd_to_run)
40 # for the optional parameters where all subparameters are known, expand expression otherwise remove totally
41 for opts_name_str in self.optset_list:
42 opts_expr_str = self._insert_known_vars(self.optset_list[opts_name_str])
43 p = re.compile("\$\[" + opts_name_str + "\]")
44 if self._contains_vars(opts_expr_str):
45 cmd_to_run = p.sub("", cmd_to_run)
46 else:
47 cmd_to_run = p.sub(opts_expr_str, cmd_str)
49 print cmd_to_run
51 class RenderCommands:
52 def __init__(self):
53 self.command_list = {}
54 self._read_config()
56 def _read_config(self):
57 doc = libxml2.parseFile("rendercommands.xml")
58 cmd_xmllist = doc.xpathEval( '//command')
60 for cmdnode in cmd_xmllist:
61 cmd_name_str = None
62 cmd_call_str = None
63 for p in cmdnode.properties:
64 if p.name=="name":
65 cmd_name_str = str(p.children)
66 elif p.name=="call":
67 cmd_call_str = str(p.children)
69 optset_list = {}
71 if cmdnode.children:
72 for optset in cmdnode.children:
73 if optset.properties:
74 opts_name_str = None
75 opts_expr_str = None
76 for p in optset.properties:
77 if p.name == "name":
78 opts_name_str = str(p.children)
79 elif p.name == "expr":
80 opts_expr_str = str(p.children)
81 if opts_name_str == None or opts_expr_str == None:
82 print opts_name_str
83 print opts_expr_str
84 raise "optionsetting must have both name and expr"
86 optset_list[opts_name_str] = opts_expr_str
88 if cmd_name_str == None or cmd_call_str == None:
89 print cmd_name_str
90 print cmd_call_str
91 raise "command must have both name and call"
93 self.command_list[cmd_name_str] = RenderCommand(cmd_name_str, cmd_call_str, optset_list)
95 def __iter__(self):
96 return self.command_list.values().__iter__()
98 def main():
99 commands = RenderCommands()
101 for c in commands:
102 c.set_var("in", "source.avi")
103 c.set_var("out", "dest.avi")
104 c.execute()
106 if __name__ == "__main__":
107 main()