From b087dd23bda803b5e3e98c43319f20e6697b0636 Mon Sep 17 00:00:00 2001 From: treeform Date: Sat, 29 May 2021 16:26:31 -0700 Subject: [PATCH] Add fill leak checker (use -d:pixieLeakCheck). --- src/pixie/paths.nim | 6 +++++- tests/fuzz_leaks.nim | 30 ++++++++++++++++++++++++++++++ tests/fuzz_leaks2.nim | 36 ++++++++++++++++++++++++++++++++++++ tests/fuzz_leaks3.nim | 14 ++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/fuzz_leaks.nim create mode 100644 tests/fuzz_leaks2.nim create mode 100644 tests/fuzz_leaks3.nim diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim index 5dbcbd6..6ba6eb5 100644 --- a/src/pixie/paths.nim +++ b/src/pixie/paths.nim @@ -1164,6 +1164,10 @@ template computeCoverages( count += winding + when defined(pixieLeakCheck): + if prevAt != size.x and count != 0: + echo "Leak detected: ", count, " @ ", prevAt, " ", y + proc fillShapes( image: Image, shapes: seq[seq[Vec2]], @@ -1359,7 +1363,7 @@ proc strokeShapes( miterLimit: float32, dashes: seq[float32] ): seq[seq[Vec2]] = - if strokeWidth == 0: + if strokeWidth <= 0: return let miterAngleLimit = miterLimitToAngle(miterLimit) diff --git a/tests/fuzz_leaks.nim b/tests/fuzz_leaks.nim new file mode 100644 index 0000000..c15d3b3 --- /dev/null +++ b/tests/fuzz_leaks.nim @@ -0,0 +1,30 @@ +import pixie, random + +when not defined(pixieLeakCheck): + quit("Requires -d:pixieLeakCheck") + +randomize() + +for i in 0 ..< 100_000: + + let image = newImage(400, 400) + image.fill(rgba(255, 255, 255, 255)) + + let ctx = newContext(image) + ctx.translate(200, 200) + ctx.scale(vec2(rand(0.1 .. 1.2), rand(0.1 .. 1.2))) + ctx.rotate(rand(0.0 .. 2*PI)) + + ctx.strokeStyle = "#000000" + ctx.lineCap = sample([lcRound, lcButt, lcSquare]) + ctx.lineJoin = sample([ljMiter, ljRound, ljBevel]) + ctx.miterLimit = 2 + ctx.lineWidth = rand(0.1 .. 20.0) + + ctx.moveTo(rand(-100 .. 100).float32, rand(-100 .. 100).float32) + for i in 0 ..< rand(0 .. 100): + ctx.lineTo(rand(-100 .. 100).float32, rand(-100 .. 100).float32) + ctx.stroke() + + # image.writeFile("tests/fuzz_leaks.png") + # break diff --git a/tests/fuzz_leaks2.nim b/tests/fuzz_leaks2.nim new file mode 100644 index 0000000..b9a0570 --- /dev/null +++ b/tests/fuzz_leaks2.nim @@ -0,0 +1,36 @@ +import pixie, random, os + +when not defined(pixieLeakCheck): + quit("Requires -d:pixieLeakCheck") + +randomize() + +for i in 0 ..< 100_000: + let image = newImage(400, 400) + image.fill(rgba(255, 255, 255, 255)) + + let ctx = newContext(image) + + ctx.translate(200, 200) + ctx.scale(vec2(rand(0.1 .. 1.7), rand(0.1 .. 1.7))) + ctx.rotate(rand(0.0 .. 2*PI)) + + ctx.strokeStyle = "#000000" + ctx.lineCap = sample([lcRound, lcButt, lcSquare]) + ctx.lineJoin = sample([ljMiter, ljRound, ljBevel]) + ctx.lineWidth = rand(0.1 .. 1.0) + + var first = true + var number = rand(2 .. 100) + for a in 0 .. number: + let th = a.float32 / number.float32 * PI + let pos = vec2(sin(th) * 100, cos(th) * 100) + if first: + ctx.moveTo(pos) + first = false + else: + ctx.lineTo(pos) + ctx.stroke() + + # image.writeFile("tests/fuzz_leaks2.png") + # break diff --git a/tests/fuzz_leaks3.nim b/tests/fuzz_leaks3.nim new file mode 100644 index 0000000..4834b42 --- /dev/null +++ b/tests/fuzz_leaks3.nim @@ -0,0 +1,14 @@ +import pixie, random, pixie/fileformats/svg + +when not defined(pixieLeakCheck): + quit("Requires -d:pixieLeakCheck") + +randomize() + +let data = readFile("tests/images/svg/Ghostscript_Tiger.svg") + +for i in 0 ..< 100_000: + var image = decodeSvg(data, rand(300 .. 1800), rand(30 .. 1800)) + + # image.writeFile("tests/fuzz_leaks3.png") + # break