Clone in a terminal:
Commit df1db3a
Johan Mattsson - 2015-10-15T10:46:08+00:00
df1db3a741eaa89def2d65d8bcb761fd14797d0ejohan.mattsson.m@gmail.com

Fuzz testing

Changed files (16)

Diff

diff --git a/birdfont-test.sh b/birdfont-test.shnew file mode 100755index 0000000..ae24da8--- /dev/null+++ b/birdfont-test.sh@@ -0,0 +1,5 @@+#!/bin/sh+export LD_LIBRARY_PATH="./build/:./build/bin:$LD_LIBRARY_PATH"+PKG_PATH=$(dirname "$(readlink -f "$0")")+cd "${PKG_PATH}"+./build/bin/birdfont-test "$@"diff --git a/birdfont-test/TestRunner.vala b/birdfont-test/TestRunner.valanew file mode 100644index 0000000..3893809--- /dev/null+++ b/birdfont-test/TestRunner.vala@@ -0,0 +1,134 @@+using BirdFont;++namespace BirdFont {++public class TestRunner : NativeWindow, GLib.Object  {+	public static void fuzz_test (string[] arg) {+		if (arg.length != 3) {+			print ("Usage: " + arg[0] + " TEST FILE\n");+			print ("TEST parameter can be BF or SVG\n");+			Process.exit (0);+		}+		+		string type = arg[1];+		string file = arg[2];+		+		if (type == "SVG") {+			File f = File.new_for_path (file);+			Font font = new Font ();+			import_svg_file (font, f);+		} else if (type == "BF") {+			Font font = new Font ();+			font.set_font_file (file);+			font.load ();+		}+		+		Process.exit (0);+	}+	+	public void file_chooser (string title, FileChooser file_chooser_callback, uint flags) {+	}+	+	public void update_window_size () {+	}+	+	public string get_clipboard_data (){+		return "";+	}++	public void set_clipboard (string data) {+	}+	+	public void set_inkscape_clipboard (string data) {+	}++	public void set_scrollbar_size (double size) {+	}+	+	public void set_scrollbar_position (double position) {+	}+	+	public void font_loaded () {+	}++	public void quit () {+		Process.exit (0);+	}++	public bool convert_to_png (string from, string to) {+		return false;+	}+	+	public void export_font () {+	}++	public void load () {+	}+	+	public void save () {+	}+	+	public void load_background_image () {+	}++	public void run_background_thread (Task t) {+		unowned Thread<void*> bg;+		+		MenuTab.start_background_thread ();+		+		try {+			bg = Thread.create<void*> (t.perform_task, true);+		} catch (GLib.Error e) {+			warning (e.message);+		}+	}++	public void run_non_blocking_background_thread (Task t) {+		unowned Thread<void*> bg;+		+		try {+			bg = Thread.create<void*> (t.perform_task, true);+		} catch (GLib.Error e) {+			warning (e.message);+		}+	}+	+	public void set_clipboard_text (string text) {+	}+	+	public string get_clipboard_text () {+		return "";+	}+	+	public bool can_export () {+		return true;+	}++	public void set_cursor (int visible) {+	}++	public double get_screen_scale () {+		return 1;+	}+}++}++public static int main (string[] arg) {+	TestRunner runner;+	MainWindow window;+	BirdFont.BirdFont birdfont;+	string[] birdfont_args = new string[1];++	birdfont_args[0] = arg[0];+	birdfont = new BirdFont.BirdFont ();+	birdfont.init (birdfont_args, null, "birdfont");+	+	window = new MainWindow ();+	runner = new TestRunner ();	++	window.set_native (runner);+	TestRunner.fuzz_test (arg);+	+	return 0;+}diff --git a/birdfont-test/illustrator.svg b/birdfont-test/illustrator.svgnew file mode 100644index 0000000..f8f4e1d--- /dev/null+++ b/birdfont-test/illustrator.svg@@ -0,0 +1,77 @@+<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In  -->+<svg version="1.1"+         xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"+         x="0px" y="0px" width="41.7px" height="41.7px" viewBox="0 0 41.7 41.7" overflow="scroll" enable-background="new 0 0 41.7 41.7"+         xml:space="preserve">+<defs>+</defs>+<circle cx="20.8" cy="20.8" r="20.8"/>++  <g+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     id="layer1">++  <polygon fill="red" stroke="blue" stroke-width="2" +            points="350,75  379,161 469,161 397,215+                    423,301 350,250 277,301 303,215+                    231,161 321,161" />++  <polygon fill="lime" stroke="blue" stroke-width="1" +            points="850,75  958,137.5 958,262.5+                    850,325 742,262.6 742,137.5" />++  <polyline fill="none" stroke="blue" stroke-width="3" +            points="50,375+                    150,375 150,325 250,325 250,375+                    350,375 350,250 450,250 450,375+                    550,375 550,175 650,175 650,375+                    750,375 750,100 850,100 850,375+                    950,375 950,25 1050,25 1050,375+                    1150,375" />+  +  <ellipse+       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:10.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"+       id="path4136"+       cx="171.42857"+       cy="368.07651"+       rx="82.85714"+       ry="18.571428" />+    <ellipse+       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:10.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"+       id="path4138"+       cx="170"+       cy="249.50505"+       rx="24.285715"+       ry="25.714285" />+    <circle+       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"+       id="path4140"+       cx="177.14285"+       cy="472.36221"+       r="28.571428" />+    <path+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"+       d="M -80,209.50506 -94.285714,515.21935"+       id="path4224"+       inkscape:connector-curvature="0" />+    <path+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"+       d="m -352.54324,209.89499 -22.22335,262.63966"+       id="path4235"+       inkscape:connector-curvature="0" />+    <path+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:20.4;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"+       d="m -345.47217,495.76816 78.7919,-2.02031 16.16244,-191.92898 80.8122,8.08122 10.10153,-103.03556"+       id="path4237"+       inkscape:connector-curvature="0" />+    <path+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:46.79999924;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"+       d="m -337.14286,592.3622 191.42857,20 62.857151,157.14286 -325.714291,-14.28572 z"+       id="path4239"+       inkscape:connector-curvature="0" />+  </g>++</svg>++diff --git a/birdfont-test/inkscape.svg b/birdfont-test/inkscape.svgnew file mode 100644index 0000000..f230dea--- /dev/null+++ b/birdfont-test/inkscape.svg@@ -0,0 +1,108 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!-- Created with Inkscape (http://www.inkscape.org/) -->++<svg+   xmlns:dc="http://purl.org/dc/elements/1.1/"+   xmlns:cc="http://creativecommons.org/ns#"+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"+   xmlns:svg="http://www.w3.org/2000/svg"+   xmlns="http://www.w3.org/2000/svg"+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"+   width="210mm"+   height="297mm"+   viewBox="0 0 744.09448819 1052.3622047"+   id="svg2"+   version="1.1"+   inkscape:version="0.91 r13725"+   sodipodi:docname="drawing.svg">+  <defs+     id="defs4" />+  <sodipodi:namedview+     id="base"+     pagecolor="#ffffff"+     bordercolor="#666666"+     borderopacity="1.0"+     inkscape:pageopacity="0.0"+     inkscape:pageshadow="2"+     inkscape:zoom="0.49497475"+     inkscape:cx="205.26829"+     inkscape:cy="569.09246"+     inkscape:document-units="px"+     inkscape:current-layer="layer1"+     showgrid="false"+     inkscape:window-width="1213"+     inkscape:window-height="734"+     inkscape:window-x="67"+     inkscape:window-y="27"+     inkscape:window-maximized="1" />+  <metadata+     id="metadata7">+    <rdf:RDF>+      <cc:Work+         rdf:about="">+        <dc:format>image/svg+xml</dc:format>+        <dc:type+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />+        <dc:title />+      </cc:Work>+    </rdf:RDF>+  </metadata>++  <g transform="translate(300 200)">+    <ellipse rx="250" ry="100" fill="red"  />+  </g>++  <ellipse transform="translate(900 200) rotate(-30)" +        rx="250" ry="100"+        fill="none" stroke="blue" stroke-width="20"  />++  <circle cx="600" cy="200" r="100"+           fill="red" stroke="blue" stroke-width="10"  />++  <polygon fill="red" stroke="blue" stroke-width="2" +            points="350,75  379,161 469,161 397,215+                    423,301 350,250 277,301 303,215+                    231,161 321,161" />++  <polygon fill="lime" stroke="blue" stroke-width="1" +            points="850,75  958,137.5 958,262.5+                    850,325 742,262.6 742,137.5" />++  <polyline fill="none" stroke="blue" stroke-width="3" +            points="50,375+                    150,375 150,325 250,325 250,375+                    350,375 350,250 450,250 450,375+                    550,375 550,175 650,175 650,375+                    750,375 750,100 850,100 850,375+                    950,375 950,25 1050,25 1050,375+                    1150,375" />++  <g+     inkscape:label="Layer 1"+     inkscape:groupmode="layer"+     id="layer1">+    <path+       id="path3336"+       d="m 530.21436,96.442957 c 0.22955,-2.49294 0.22072,-4.99913 0.23615,-7.50037 0.0759,-3.49913 0.31114,-7.00494 0.69108,-10.48499 0.19569,-2.73094 1.18973,-5.2346 2.38578,-7.66023 1.34792,-2.3572 3.1598,-4.42284 4.87878,-6.51609 4.81231,-5.56814 11.71957,-8.69924 18.21635,-11.93448 1.35154,-0.77198 2.8578,-1.08515 4.31892,-1.54228 1.38128,-0.43215 2.69952,-0.98075 4.09797,-1.37133 3.51161,-0.70063 7.07652,-1.08281 10.64527,-1.36103 3.17741,-0.27503 6.36338,-0.37859 9.55067,-0.43948 33.21929,1.16497 38.71465,48.60176 37.39069,72.693173 -0.13208,3.02811 -0.43859,6.03452 -0.76695,9.04605 -0.38008,3.09515 -0.82911,6.17888 -1.10014,9.28677 -0.21607,2.34566 -0.22316,4.70361 -0.27745,7.05685 -0.73383,8.30678 -1.87854,16.73092 0.0141,24.61604 6.3008,10.40178 13.98933,18.83499 23.79271,23.9935 2.01853,0.89311 3.93853,1.99996 6.01798,2.74894 1.56008,0.54266 2.97671,1.35695 4.4368,2.11118 l -10.54961,6.91182 0,0 c -1.41603,-0.75423 -2.86204,-1.42739 -4.36161,-2.0018 -9.37867,-4.46491 -19.92902,-12.04992 -25.48795,-19.83017 -1.80824,-2.52871 -3.57924,-5.15244 -4.724,-8.05549 -0.71299,-2.84947 -1.34614,-5.72496 -1.18252,-8.68175 -0.008,-7.78416 0.50498,-15.91494 1.14884,-23.31982 0.36378,-3.11371 0.91446,-6.20527 1.14332,-9.33363 0.39488,-2.98018 0.70133,-5.96077 0.77775,-8.9689 0.17449,-2.75094 0.25889,-5.45636 -0.58242,-8.1294 -0.33448,-1.16006 -0.57513,-1.78053 -0.67591,-2.99605 -0.41995,-22.903383 -3.57299,-49.580213 -27.58493,-58.741593 -2.46062,-0.83394 -4.93114,-1.22289 -7.53548,-1.0467 -3.07571,0.0101 -6.15342,0.0774 -9.22111,0.31279 -3.59705,0.34292 -7.20502,0.80902 -10.70619,1.7231 -2.76243,0.88754 -5.56402,1.72663 -8.17464,3.00611 -4.22478,2.20497 -4.33451,2.29504 7.38773,-4.44001 0.48452,-0.27838 -0.95099,0.58917 -1.40182,0.91931 -1.16396,0.8524 -2.14842,1.91104 -3.18083,2.90972 -1.69282,2.02276 -3.37571,4.07297 -4.88132,6.23646 -1.29745,2.29607 -2.42205,4.67462 -2.7175,7.33146 -0.54461,3.40741 -0.77769,6.89464 -0.77396,10.34213 0.0141,2.42092 -9.1e-4,4.84798 0.23615,7.25973 l -11.48213,5.85046 z"+       inkscape:connector-curvature="0"+       sodipodi:nodetypes="ccccccscccccccccccccccccccccccccccssccccccc" />+    <path+       id="path3338"+       d="m 590.62407,128.42627 c -2.87235,-0.55223 -5.75325,-0.23469 -8.63201,0.0356 -3.3226,0.34662 -6.64475,0.67807 -9.962,1.0819 -55.02,9.80749 -43.95719,56.49419 -5.57685,65.93053 2.28604,0.78259 4.3684,1.95945 6.71033,2.58207 50.40294,-4.86553 -0.3861,2.98016 47.21599,-15.86941 l 0,0 c -1.61624,1.08719 -3.00508,2.43643 -4.56508,3.60366 -15.13345,6.20768 -12.48911,15.00919 -46.32017,19.61022 -2.22912,0.16359 -4.51176,0.42763 -6.68128,-0.27092 -2.31813,-0.75589 -4.45734,-1.91593 -6.76549,-2.70385 -2.33965,-0.95913 -4.74318,-1.77659 -6.98725,-2.95342 -47.68005,-22.56126 -22.46711,-69.50933 21.04915,-75.64057 3.85796,-0.76447 7.72173,-1.22449 11.64271,-1.53847 11.77804,-2.16543 23.1665,-0.66046 34.49525,0.14803 2.06008,0.14905 4.10767,0.50696 6.16658,0.57015 -9.97576,9.21189 -19.8907,7.31984 -31.78988,5.41459 z"+       inkscape:connector-curvature="0"+       sodipodi:nodetypes="ccccccccccccccccc" />+    <rect+       style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:10.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"+       id="rect4135"+       width="120"+       height="120"+       x="535.12256"+       y="298.07648" />+    <path+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:14.50000038;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"+       d="m 527.29963,490.71739 131.31983,0"+       id="path4137"+       inkscape:connector-curvature="0" />+  </g>+</svg>diff --git a/configure b/configureindex 5493cab..8383c79 100755--- a/configure+++ b/configure@@ -15,7 +15,8 @@ TARGETS = ['libbirdfont',            'birdfont',             'birdfont-autotrace',            'birdfont-export',-           'birdfont-import']+           'birdfont-import',+           'birdfont-test']             VERSION = version.VERSION diff --git a/dodo.py b/dodo.pyindex 4dfbb9c..83fa277 100644--- a/dodo.py+++ b/dodo.py@@ -35,7 +35,8 @@ DOIT_CONFIG = {         'birdfont',          'birdfont-autotrace',         'birdfont-export',-        'birdfont-import'+        'birdfont-import',+        'birdfont-test'         ],     } @@ -424,3 +425,68 @@ def task_build ():     return  {         'actions': ['echo "Build"'],         }++def make_birdfont_test(target_binary, deps):+    valac_command = config.VALAC + """\+        -C \+        --vapidir=./ \+        --basedir build/birdfont-test/ \+        """ + config.NON_NULL + """ \+        """ + config.VALACFLAGS.get("birdfont-test", "") + """ \+        --enable-experimental \+        birdfont-test/*.vala \+		--vapidir=./ \+		--pkg """ + config.GEE + """ \+		--pkg gio-2.0  \+		--pkg cairo \+		--pkg libsoup-2.4 \+		--pkg gdk-pixbuf-2.0 \+		--pkg webkitgtk-3.0 \+		--pkg libnotify \+		--pkg xmlbird \+		--pkg libbirdfont+        """++    cc_command = config.CC + " " + config.CFLAGS.get("birdfont-test", "") + """ \+        -c C_SOURCE \+		-D 'GETTEXT_PACKAGE="birdfont"' \+        -I./build/libbirdfont \+		$(pkg-config --cflags sqlite3) \+		$(pkg-config --cflags """ + config.GEE + """) \+		$(pkg-config --cflags gio-2.0) \+		$(pkg-config --cflags cairo) \+		$(pkg-config --cflags glib-2.0) \+		$(pkg-config --cflags gdk-pixbuf-2.0) \+		$(pkg-config --cflags webkitgtk-3.0) \+		$(pkg-config --cflags libnotify) \+        -o OBJECT_FILE"""+        +    linker_command = config.CC + " " + config.LDFLAGS.get("birdfont-test", "") + """ \+        build/birdfont-test/*.o \+		-L./build/bin -lbirdfont \+		$(pkg-config --libs sqlite3) \+		$(pkg-config --libs """ + config.GEE + """) \+		$(pkg-config --libs gio-2.0) \+		$(pkg-config --libs cairo) \+		$(pkg-config --libs glib-2.0) \+		$(pkg-config --libs gdk-pixbuf-2.0) \+		$(pkg-config --libs webkitgtk-3.0) \+		$(pkg-config --libs xmlbird) \+		$(pkg-config --libs libnotify) \+		-L./build -L./build/bin -l birdgems\+        -o build/bin/""" + target_binary++    test = Builder('birdfont-test',+                   valac_command, +                   cc_command,+                   linker_command,+                   target_binary,+                   None,+                   deps)+			+    yield test.build()++def task_birdfont_test():+    yield make_birdfont_test('birdfont-test', ['libbirdgems.so', 'libbirdfont.so'])++diff --git a/libbirdfont/Argument.vala b/libbirdfont/Argument.valaindex 2902091..721ffd1 100644--- a/libbirdfont/Argument.vala+++ b/libbirdfont/Argument.vala@@ -79,6 +79,7 @@ public class Argument : GLib.Object { 				a == "--log" || 				a == "--windows" || 				a == "--parse-ucd" ||+				a == "--fuzz" || 				a == "--codepages") { 				prev = a; 				i++;diff --git a/libbirdfont/Glyph.vala b/libbirdfont/Glyph.valaindex e325961..8746ef9 100644--- a/libbirdfont/Glyph.vala+++ b/libbirdfont/Glyph.vala@@ -1337,9 +1337,7 @@ public class Glyph : FontDisplay { 			if (p.is_editable ()) { 				r = true; 				p.set_editable (false);-			}-			-			p.create_full_stroke (); // cache stroke+			}			 		} 		 		open = false;diff --git a/libbirdfont/ImportUtils.vala b/libbirdfont/ImportUtils.valaindex 0c45601..59bd968 100644--- a/libbirdfont/ImportUtils.vala+++ b/libbirdfont/ImportUtils.vala@@ -93,7 +93,7 @@ public static int run_import (string[] arg) { 	return 0; } -static bool import_svg_file (Font font, File svg_file) {+public static bool import_svg_file (Font font, File svg_file) { 	string file_name = (!) svg_file.get_basename (); 	string glyph_name; 	StringBuilder n;diff --git a/libbirdfont/Path.vala b/libbirdfont/Path.valaindex 35de63d..7721ed4 100644--- a/libbirdfont/Path.vala+++ b/libbirdfont/Path.vala@@ -2443,6 +2443,7 @@ public class Path : GLib.Object { 			return; 		} 		+		print(@"Create full stroke for $(points.size) points.\n"); 		StrokeTask task = new StrokeTask (this); 		MainWindow.native_window.run_non_blocking_background_thread (task); 		@@ -2475,7 +2476,10 @@ public class Path : GLib.Object { 		} 		 		StrokeTool s = new StrokeTool ();+		Test t = new Test.time ("fast stroke"); 		fast_stroke = s.get_stroke_fast (this, stroke);+		t.print();+		 		return (!) fast_stroke; 	} 	diff --git a/libbirdfont/PenTool.vala b/libbirdfont/PenTool.valaindex a155e14..9c78ae6 100644--- a/libbirdfont/PenTool.vala+++ b/libbirdfont/PenTool.vala@@ -186,7 +186,10 @@ public class PenTool : Tool { 					p.get_last_point ().set_reflective_handles (false); 				} 				-				p.create_full_stroke (); // cache good stroke+				// cache good stroke+				if (p.full_stroke == null) {+					p.create_full_stroke ();+				} 			} 			 			// select or deselect pointsdiff --git a/libbirdfont/StrokeTask.vala b/libbirdfont/StrokeTask.valaindex dc92412..2a559cc 100644--- a/libbirdfont/StrokeTask.vala+++ b/libbirdfont/StrokeTask.vala@@ -36,8 +36,12 @@ public class StrokeTask : Task { 		StrokeTool tool = new StrokeTool.with_task (this); 		 		w = background_path.stroke;+		+		Test t = new Test.time ("full stroke"); 		stroke = tool.get_stroke (background_path, w);-+		t.print ();+		print(@"Cancelled: $(is_cancelled ())\n");+		 		IdleSource idle = new IdleSource ();  		idle.set_callback (() => {	 			if (!is_cancelled ()) {diff --git a/libbirdfont/StrokeTool.vala b/libbirdfont/StrokeTool.valaindex 0e10d45..8749579 100644--- a/libbirdfont/StrokeTool.vala+++ b/libbirdfont/StrokeTool.vala@@ -1533,6 +1533,10 @@ public class StrokeTool : GLib.Object { 	PathList get_parts_self (Path path, PathList? paths = null) { 		PathList pl; 		PathList r;+		+		if (task.is_cancelled ()) {+			return new PathList ();+		}  		r = paths == null ? new PathList () : (!) paths; 		pl = split (path);@@ -2847,8 +2851,9 @@ public class StrokeTool : GLib.Object { 			side2.add_point (previous_inside); 		} -		min_increment = 0.013;+		min_increment = 0.02; // 0.013 		+		Test t1 = new Test.time ("generate"); 		for (i = 0; i < size; i++) { 			p1 = path.points.get (i % path.points.size); 			p2 = path.points.get ((i + 1) % path.points.size);@@ -2858,9 +2863,9 @@ public class StrokeTool : GLib.Object { 				return new PathList (); 			} 					-			tolerance = 0.01; //  0.13 / sqrt (stroke_width)+			tolerance = 0.01; 			step_increment = 1.05;-			step_size = 0.039; // / stroke_width;+			step_size = 0.039;  			corner1 = new EditPoint (); 			@@ -2883,7 +2888,7 @@ public class StrokeTool : GLib.Object { 		 			step = step_size; 			keep = 0;-			step_size = 0.01;+			step_size = 0.05; // 0.01  			while (step < 1 - 2 * step_size) { 				Path.get_point_for_step (p1, p2, step, out x, out y);@@ -2913,7 +2918,7 @@ public class StrokeTool : GLib.Object { 					step_size *= step_increment; 					continue; 				}-			+				 				get_segment (thickness, step, step_size, p1, p2, out corner1); 				get_segment (-thickness, step, step_size, p1, p2, out corner1_inside); @@ -2983,7 +2988,8 @@ public class StrokeTool : GLib.Object { 					add_corner (side2, previous_inside, start, p2.copy (), thickness); 				} 			}-				+			t1.print();+			 			if (fast) { 				EditPoint s1, s2; 				bool open;@@ -3039,7 +3045,9 @@ public class StrokeTool : GLib.Object { 			 			side2.reverse (); 			+			Test t2 = new Test.time ("merge2"); 			pl = merge_stroke_parts (path, side1, side2);+			t2.print(); 		}  		if (fast) {diff --git a/libbirdfont/SvgParser.vala b/libbirdfont/SvgParser.valaindex ef2aa66..57da814 100644--- a/libbirdfont/SvgParser.vala+++ b/libbirdfont/SvgParser.vala@@ -667,6 +667,7 @@ public class SvgParser { 		PathList npl = new PathList (); 		SvgStyle style = new SvgStyle (); 		bool hidden = false;+		EditPoint ep; 		 		x = 0; 		y = 0;@@ -730,10 +731,17 @@ public class SvgParser { 					 		p = new Path ();	 		-		p.add (bezier_points[0].x0, bezier_points[0].y0);-		p.add (bezier_points[1].x0, bezier_points[1].y0);-		p.add (bezier_points[2].x0, bezier_points[2].y0);-		p.add (bezier_points[3].x0, bezier_points[3].y0);+		ep = p.add (bezier_points[0].x0, bezier_points[0].y0);+		ep.set_point_type (PointType.CUBIC);+		+		ep = p.add (bezier_points[1].x0, bezier_points[1].y0);+		ep.set_point_type (PointType.CUBIC);+		+		ep = p.add (bezier_points[2].x0, bezier_points[2].y0);+		ep.set_point_type (PointType.CUBIC);+		+		ep = p.add (bezier_points[3].x0, bezier_points[3].y0);+		ep.set_point_type (PointType.CUBIC); 						 		p.close (); 		p.create_list ();@@ -1570,6 +1578,7 @@ public class SvgParser { 		if (format == SvgFormat.ILLUSTRATOR) { 			path_list = create_paths_illustrator (bezier_points, bi); 		} else {+			print(d + "\n\n"); // FIXME: DELETE 			path_list = create_paths_inkscape (bezier_points, bi); 		} @@ -1619,6 +1628,13 @@ public class SvgParser { 		return_if_fail (b.length != 0); 		return_if_fail (b[0].type != 'z'); 		return_if_fail (num_b < b.length);++		if (num_b == 2) {+			left_x = b[0].x0 + (b[1].x0 - b[0].x0) / 3.0;+			left_y = b[0].y0 + (b[1].y0 - b[0].y0) / 3.0;+			last_type = PointType.LINE_CUBIC;+			return;+		} 		 		for (int i = start_index; i < num_b; i++) { 			switch (b[i].type) {@@ -1634,6 +1650,9 @@ public class SvgParser { 			} 			 			if (found || i + 1 == num_b) {+				+				return_if_fail (i >= 1);+				 				if (b[i - 1].type == 'Q') { 					return_if_fail (i >= 1); 					left_x = b[i - 1].x0;@@ -1649,7 +1668,7 @@ public class SvgParser { 					left_x = b[i - 1].x1; 					left_y = b[i - 1].y1; 					last_type = PointType.CUBIC;-				}else if (b[i - 1].type == 'L' || last.type == 'M') {+				} else if (b[i - 1].type == 'L' || last.type == 'M') { 					return_if_fail (i >= 2); // FIXME: -2 can be C or L 					left_x = b[i - 2].x0 + (b[i - 1].x0 - b[i - 2].x0) / 3.0; 					left_y = b[i - 2].y0 + (b[i - 1].y0 - b[i - 2].y0) / 3.0;diff --git a/scripts/builder.py b/scripts/builder.pyindex a439d26..ed258ab 100644--- a/scripts/builder.py+++ b/scripts/builder.py@@ -105,7 +105,7 @@ class Builder(object):             object_path = path.join(build_directory, object_file)             command = command.replace('OBJECT_FILE', object_path)             yield {-                'basename': 'compile ' + path.basename(csource),+                'basename': 'compile ' + csource,                 'file_dep': [build_file, csource] + bindep + copied_cheader,                 'actions': [command],                 'targets': [path.join(build_directory, object_file)],diff --git a/scripts/fuzzsvg.py b/scripts/fuzzsvg.pynew file mode 100755index 0000000..2d50775--- /dev/null+++ b/scripts/fuzzsvg.py@@ -0,0 +1,34 @@+#!/usr/bin/python3++import subprocess+from os import path++from run import run++def fuzz_svg_import():+    fuzz_svg ('birdfont-test/inkscape.svg')+    fuzz_svg ('birdfont-test/illustrator.svg')++def fuzz_svg (file):+    run ("mkdir -p build/fuzz")+    run ("mkdir -p build/fuzz/bugs")+    run ("radamsa " + file + " > build/fuzz/a.svg")++    cmd = "./birdfont-test.sh SVG build/fuzz/a.svg"+    print('Running: ' + cmd)+    process = subprocess.Popen (cmd, shell=True)+    process.communicate()[0]+    if not process.returncode == 0:+        print("Error: " + cmd)+        print("A bug was found.")+        +        i = 0+        while path.isfile ('build/bugs/a_' + str(i) + '.svg'):+            i = i + 1+			+        run ('mv build/fuzz/a.svg attic/fuzz/bugs/a_' + str(i) + '.svg')++    run ("rm -f build/fuzz/a.svg")++while True:+    fuzz_svg_import ()

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112