def decodeCriteria(self, typeCriteria, getterCriteria): ''' Exploit that provides the decoder for the criteria. @param typeCriteria: TypeCriteria The criteria type to decode. @param getterCriteria: callable(object) -> object The getter used to get the criteria from the target object. @return: callable(**data) -> boolean The exploit that provides the criteria decoding. ''' assert isinstance( typeCriteria, TypeCriteria), 'Invalid criteria type %s' % typeCriteria assert callable(getterCriteria), 'Invalid getter %s' % getterCriteria criteria = typeCriteria.container assert isinstance(criteria, Criteria) if issubclass(typeCriteria.clazz, AsOrdered): exclude = ('ascending', 'priority') else: exclude = () children = {} for prop, typeProp in criteria.properties.items(): if prop in exclude: continue if isinstance(typeProp, Iter): assert isinstance(typeProp, Iter) setter = setterWithGetter(obtainOnObj(prop, list), list.append) propDecode = self.decodePrimitiveList(setter, typeProp.itemType) else: propDecode = self.decodePrimitive(setterOnObj(prop), typeProp) children[prop] = propDecode exploitPath = self.decodePath(children) def exploit(path, target, **data): assert isinstance(path, deque), 'Invalid path %s' % path if path: return exploitPath(path=path, target=getterCriteria(target), **data) if not criteria.main: return False data.update(path=path, target=getterCriteria(target)) for prop in criteria.main: if not children[prop](**data): return False return True return exploit
def decodeCriteria(self, typeCriteria, getterCriteria): """ Exploit that provides the decoder for the criteria. @param typeCriteria: TypeCriteria The criteria type to decode. @param getterCriteria: callable(object) -> object The getter used to get the criteria from the target object. @return: callable(**data) -> boolean The exploit that provides the criteria decoding. """ assert isinstance(typeCriteria, TypeCriteria), "Invalid criteria type %s" % typeCriteria assert callable(getterCriteria), "Invalid getter %s" % getterCriteria criteria = typeCriteria.container assert isinstance(criteria, Criteria) if issubclass(typeCriteria.clazz, AsOrdered): exclude = ("ascending", "priority") else: exclude = () children = {} for prop, typeProp in criteria.properties.items(): if prop in exclude: continue if isinstance(typeProp, Iter): assert isinstance(typeProp, Iter) setter = setterWithGetter(obtainOnObj(prop, list), list.append) propDecode = self.decodePrimitiveList(setter, typeProp.itemType) else: propDecode = self.decodePrimitive(setterOnObj(prop), typeProp) children[prop] = propDecode exploitPath = self.decodePath(children) def exploit(path, target, **data): assert isinstance(path, deque), "Invalid path %s" % path if path: return exploitPath(path=path, target=getterCriteria(target), **data) if not criteria.main: return False data.update(path=path, target=getterCriteria(target)) for prop in criteria.main: if not children[prop](**data): return False return True return exploit
def decodeInvoker(self, invoker): """ Create a decode exploit for the invoker. @param invoker: Invoker The invoker to create a parameters decoder for. @return: callable(**data) -> boolean The exploit that provides the invoker decoding. """ assert isinstance(invoker, Invoker), "Invalid invoker %s" % invoker children, ordered = {}, {} for inp in invoker.inputs: assert isinstance(inp, Input) typeInp = inp.type assert isinstance(typeInp, Type) if typeInp.isPrimitive: if isinstance(typeInp, Iter): assert isinstance(typeInp, Iter) setter = setterWithGetter(obtainOnDict(inp.name, list), list.append) inpDecode = self.decodePrimitiveList(setter, typeInp.itemType) else: inpDecode = self.decodePrimitive(setterOnDict(inp.name), typeInp) children[inp.name] = inpDecode elif isinstance(typeInp, TypeQuery): assert isinstance(typeInp, TypeQuery) assert isinstance(typeInp.query, Query) childrenQuery, orderedQuery, getterQuery = {}, {}, obtainOnDict(inp.name, inp.type.clazz) for nameEntry, classCriteria in typeInp.query.criterias.items(): getter = getterChain(getterQuery, getterOnObj(nameEntry)) childrenQuery[nameEntry] = self.decodeCriteria(typeFor(classCriteria), getter) if issubclass(classCriteria, AsOrdered): orderedQuery[nameEntry] = self.decodeSetOrder( typeInp.criteriaEntryTypeFor(nameEntry), getterQuery ) isUpdated = False if invoker.output.isOf(typeInp.owner): # If the query is a main query and also there is no name conflict then add the query children to # the main children if set(childrenQuery.keys()).isdisjoint(children.keys()) and set(orderedQuery).isdisjoint(ordered): isUpdated = True children.update(childrenQuery) ordered.update(orderedQuery) if not isUpdated: children[inp.name] = self.decodePath(childrenQuery) ordered[inp.name] = self.decodePath(orderedQuery) if self.nameOrderAsc in children: log.error("Name conflict for '%s' in %s", self.nameOrderAsc, invoker) elif self.nameOrderDesc in children: log.error("Name conflict for '%s' in %s", self.nameOrderDesc, invoker) else: exploitOrder = self.decodePath(ordered) children[self.nameOrderAsc] = self.decodeOrder(True, exploitOrder) children[self.nameOrderDesc] = self.decodeOrder(False, exploitOrder) exploitPath = self.decodePath(children) def exploit(path, **data): assert isinstance(path, str), "Invalid path %s" % path path = deque(path.split(self.separatorName)) return exploitPath(path=path, **data) return exploit
def decodeInvoker(self, invoker): ''' Create a decode exploit for the invoker. @param invoker: Invoker The invoker to create a parameters decoder for. @return: callable(**data) -> boolean The exploit that provides the invoker decoding. ''' assert isinstance(invoker, Invoker), 'Invalid invoker %s' % invoker children, ordered = {}, {} for inp in invoker.inputs: assert isinstance(inp, Input) typeInp = inp.type assert isinstance(typeInp, Type) if typeInp.isPrimitive: if isinstance(typeInp, Iter): assert isinstance(typeInp, Iter) setter = setterWithGetter(obtainOnDict(inp.name, list), list.append) inpDecode = self.decodePrimitiveList( setter, typeInp.itemType) else: inpDecode = self.decodePrimitive(setterOnDict(inp.name), typeInp) children[inp.name] = inpDecode elif isinstance(typeInp, TypeQuery): assert isinstance(typeInp, TypeQuery) assert isinstance(typeInp.query, Query) childrenQuery, orderedQuery, getterQuery = {}, {}, obtainOnDict( inp.name, inp.type.clazz) for nameEntry, classCriteria in typeInp.query.criterias.items( ): getter = getterChain(getterQuery, getterOnObj(nameEntry)) childrenQuery[nameEntry] = self.decodeCriteria( typeFor(classCriteria), getter) if issubclass(classCriteria, AsOrdered): orderedQuery[nameEntry] = self.decodeSetOrder( typeInp.criteriaEntryTypeFor(nameEntry), getterQuery) isUpdated = False if invoker.output.isOf(typeInp.owner): # If the query is a main query and also there is no name conflict then add the query children to # the main children if set(childrenQuery.keys()).isdisjoint(children.keys( )) and set(orderedQuery).isdisjoint(ordered): isUpdated = True children.update(childrenQuery) ordered.update(orderedQuery) if not isUpdated: children[inp.name] = self.decodePath(childrenQuery) ordered[inp.name] = self.decodePath(orderedQuery) if self.nameOrderAsc in children: log.error('Name conflict for \'%s\' in %s', self.nameOrderAsc, invoker) elif self.nameOrderDesc in children: log.error('Name conflict for \'%s\' in %s', self.nameOrderDesc, invoker) else: exploitOrder = self.decodePath(ordered) children[self.nameOrderAsc] = self.decodeOrder(True, exploitOrder) children[self.nameOrderDesc] = self.decodeOrder( False, exploitOrder) exploitPath = self.decodePath(children) def exploit(path, **data): assert isinstance(path, str), 'Invalid path %s' % path path = deque(path.split(self.separatorName)) return exploitPath(path=path, **data) return exploit