def fuzz_css(self): class CSSMode(Enum): Mutate = 1 Append = 2 Replace = 3 Misc = 4 css_modes = [ CSSMode.Mutate, CSSMode.Append, CSSMode.Replace, CSSMode.Misc ] css_weights = [10, 5, 1, 1] trial = 0 while trial < 10: c = Random.choices(css_modes, css_weights)[0] if c == CSSMode.Mutate: ok = self.css.mutate_css_style_rule(self.dom_context) elif c == CSSMode.Append: ok = self.css.append_css_style_rule(self.dom_context) elif c == CSSMode.Replace: ok = self.css.replace_css_style_rule(self.dom_context) else: if Random.bool(): ok = self.css.mutate_css_keyframes_rule(self.dom_context) else: ok = self.css.mutate_css_variable(self.dom_context) assert ok is not None if ok: return True trial += 1 return False
def mutate(self, context) -> bool: c = Random.selector(1 + len(self.args)) if c == 0: return self.this.mutate(context) else: arg = Random.choice(self.args) return arg.mutate(context)
def srcset(): values = [image_url()] if Random.bool(): values.append("{}w".format(Random.integer())) if Random.bool(): values.append("{}x".format(Random.integer())) return cat(values)
def list_size(): if Random.bool(): return Random.range(1, 5) else: # Special sizes that may trigger realloc # See ./animations/crash-when-animation-is-running-while-getting-value.html return Random.choice([7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65])
def animation_easing(): value = Random.choice([ "linear", "ease", "ease-in", "ease-out", "ease-in-out", "cubic-bezier" ]) if value == "cubic-bezier": value += "({})".format(seq([Random.number() for _ in range(4)])) return value
def ellipse(): values = [] if Random.bool(): values.extend([shape_radius(), shape_radius()]) if Random.bool(): values.extend(["at", position()]) return "ellipse({})".format(cat(values))
def circle(): values = [] if Random.bool(): values.append(shape_radius()) if Random.bool(): values.extend(["at", position()]) return "circle({})".format(cat(values))
def generate(self, _): c = Random.selector(3) if c == 0: self.value = "auto" elif c == 1: self.value = "auto-reverse" else: self.value = Random.integer()
def border_radius(): num = Random.range(1, 4) values = [length_percentage() for _ in range(num)] if Random.bool(): values.append("/") num = Random.range(1, 4) values.extend([length_percentage() for _ in range(num)]) return cat(values)
def generate(self, _): if Random.bool(): self.value = "accumulate" else: values = ["new"] if Random.bool(): values.extend([Random.integer() for _ in range(4)]) self.value = cat(values)
def tab_index(): c = Random.selector(3) if c == 0: return "-1" elif c == 1: return str(Random.range(0, 5)) else: return Random.integer()
def polygon(): values = [] if Random.bool(): values.append(fill_rule()) num = Random.range(2, 5) for _ in range(num): values.append("{} {}".format(length_percentage(), length_percentage())) return "polygon({})".format(seq(values))
def generate(self, _): c = Random.selector(3) if c == 0: self.value = Random.choice(["auto", "auto-start-reverse"]) elif c == 1: self.value = dv.angle() else: self.value = Random.number()
def get_svg_animatable_attribute(elem): has_regular = elem in svg_animatable_regular_attributes has_presentation = elem in svg_animatable_presentation_attributes if (not has_presentation) or (has_regular and Random.bool()): return Random.choice(svg_animatable_regular_attributes[elem]) else: return Random.choice(svg_animatable_presentation_attributes[elem])
def mutate(self, context) -> bool: if len(self.ths) == 0 or Random.bool(): # 1. add one self.append_th(context) else: # 2. replace one del self.ths[Random.selector(len(self.ths))] self.append_th(context) return True
def coords(): c = Random.selector(3) if c == 0: n = 4 elif c == 1: n = 3 else: n = Random.range(3, 5) * 2 return seq([Random.integer() for _ in range(n)])
def font_stretch_value(): if Random.bool(): return Random.choice([ "normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded" ]) else: return percentage()
def mutate(self, context) -> bool: c = Random.selector(4) if c == 0 or len(self.declarations) == 0: return self.append(context) elif c == 1: del self.declarations[Random.selector(len(self.declarations))] return self.append(context) else: decl = Random.choice(self.declarations) return decl.mutate(context)
def generate(self, _): values = [ Random.choice([ "xMinYMin", "xMidYMin", "xMaxYMin", "xMinYMid", "xMidYMid", "xMaxYMid", "xMinYMax", "xMidYMax", "xMaxYMax" ]) ] if Random.bool(): values.append(Random.choice(["meet", "slice"])) self.value = cat(values)
def generate_attributes(self, context): avail_attr_count = get_attribute_count(self.name) if avail_attr_count >= 20: total_count = TreeConfig.max_attribute_count elif avail_attr_count >= 10: total_count = Random.range(5, avail_attr_count) elif avail_attr_count >= 1: total_count = Random.range(1, avail_attr_count) else: total_count = 0 for _ in range(total_count): self.append_attribute(context)
def mutate_text(self) -> bool: if Random.bool(): if docs.is_svg_text_element(self.name): self.last_text = Random.string() return True return False else: if self.parent is None or docs.is_svg_text_element( self.parent.name): self.ahead_text = Random.string() return True return False
def generate_rel1(self, context): self.abs = None self.action = None self.repeat_num = None self.event = None self.elem = context.get_object(docs.svg_animation_elements) if self.elem is None: self.generate_abs() return self.action = Random.choice(["begin", "end", "repeat"]) if self.action == "repeat": self.repeat_num = Random.integer()
def generate(self, _): if Random.bool(): self.value = "normal" else: selectors = Random.selectors(3) values = [] if selectors[0]: values.append("fill") if selectors[1]: values.append("stroke") if selectors[2]: values.append("markers") self.value = cat(values)
def generate_api(self): # 1. select an alive object (type) obj_names = list(self.context.superset_at_line) weights = [get_api_count(name) for name in obj_names] # 2. select an api that uses the object name as |this| while True: name = Random.choices(obj_names, weights)[0] template = Random.choice(js_apis[name]) if template.satiable(self.context): api = template.instantiate() api.generate(self.context) return api
def media_query(): media_type = Random.choice(["all", "print", "screen"]) if Random.bool(): return media_type media_feature = Random.choice( ["min-width", "max-width", "min-height", "max-height", "orientation"]) if media_feature == "orientation": media_feature_value = Random.choice(["portrait", "landscape"]) else: media_feature_value = "{}px".format(Random.integer()) return "{} and ({}:{})".format(media_type, media_feature, media_feature_value)
def generate_css_rules(self, context): for _ in range(CSSConfig.max_css_count): self.append_css_style_rule(context) for rule in self.css_style_rules: for _ in range( Random.range(0, CSSConfig.max_css_selector_count - 1)): rule.append_selector(context) for _ in range(CSSConfig.max_css_decl_count - 1): rule.append_decl(context) for rule in self.css_keyframes_rules: for _ in range(Random.range(1, CSSConfig.max_css_keyframe_count)): rule.append_keyframe_rule(context)
def single(): values = [ "'{}'".format( Random.choice([ "smcp", "c2sc", "zero", "hist", "liga", "tnum", "frac", "swsh", "ss07", "dlig", "vert", "hwid", "twid", "qwid", "kern", "onum" ])) ] if Random.bool(): if Random.bool(): values.append(Random.choice(["on", "off"])) else: values.append(Random.integer()) return cat(values)
def insert_root_element(self, context): if self.full: return None if Random.selector(5) > 0: name = Random.choice(docs.html_general_child_elements) else: name = Random.choice(docs.html_other_child_elements) child = of.create_object(name) self.add_root_element(child) if child is not None: self.init_element(context, child) return child
def generate_one(self): document = Document(Random.range(TreeConfig.min_element_count, TreeConfig.max_element_count)) document.generate_nodes() document.generate_attributes() document.generate_css_rules() document.generate_js_functions() return document
def generate(self, context): if Random.bool(): self.cla = context.global_context.get_token("class") self.elem = None else: self.cla = None self.elem = context.global_context.get_object(docs.elements)