FuzzDrawFunctions.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * Copyright 2016 Mozilla Foundation
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "fuzz/Fuzz.h"
  8. #include "include/core/SkBitmap.h"
  9. #include "include/core/SkCanvas.h"
  10. #include "include/core/SkFont.h"
  11. #include "include/core/SkImage.h"
  12. #include "include/core/SkPath.h"
  13. #include "include/core/SkSurface.h"
  14. #include "include/core/SkTextBlob.h"
  15. #include "include/core/SkTypeface.h"
  16. #include "src/core/SkClipOpPriv.h"
  17. static const int kBmpSize = 24;
  18. static const int kMaxX = 250;
  19. static const int kMaxY = 250;
  20. static const int kPtsLen = 10;
  21. static const int kTxtLen = 5;
  22. static void init_string(Fuzz* fuzz, char* str, size_t bufSize) {
  23. for (size_t i = 0; i < bufSize-1; ++i) {
  24. fuzz->nextRange(&str[i], 0x20, 0x7E); // printable ASCII
  25. }
  26. str[bufSize-1] = '\0';
  27. }
  28. // make_paint mostly borrowed from FilterFuzz.cpp
  29. static void init_paint(Fuzz* fuzz, SkPaint* p) {
  30. bool b;
  31. fuzz->next(&b);
  32. p->setAntiAlias(b);
  33. uint8_t tmp_u8;
  34. fuzz->nextRange(&tmp_u8, 0, (int)SkBlendMode::kLastMode);
  35. p->setBlendMode(static_cast<SkBlendMode>(tmp_u8));
  36. SkColor co;
  37. fuzz->next(&co);
  38. p->setColor(co);
  39. fuzz->next(&b);
  40. p->setDither(b);
  41. fuzz->nextRange(&tmp_u8, 0, (int)kHigh_SkFilterQuality);
  42. p->setFilterQuality(static_cast<SkFilterQuality>(tmp_u8));
  43. fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kLast_Cap);
  44. p->setStrokeCap(static_cast<SkPaint::Cap>(tmp_u8));
  45. fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kLast_Join);
  46. p->setStrokeJoin(static_cast<SkPaint::Join>(tmp_u8));
  47. SkScalar sc;
  48. fuzz->next(&sc);
  49. p->setStrokeMiter(sc);
  50. fuzz->next(&sc);
  51. p->setStrokeWidth(sc);
  52. fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kStrokeAndFill_Style);
  53. p->setStyle(static_cast<SkPaint::Style>(tmp_u8));
  54. }
  55. static void init_bitmap(Fuzz* fuzz, SkBitmap* bmp) {
  56. uint8_t colorType;
  57. fuzz->nextRange(&colorType, 0, (int)kLastEnum_SkColorType);
  58. // ColorType needs to match what the system configuration is.
  59. if (colorType == kRGBA_8888_SkColorType || colorType == kBGRA_8888_SkColorType) {
  60. colorType = kN32_SkColorType;
  61. }
  62. bool b;
  63. fuzz->next(&b);
  64. SkImageInfo info = SkImageInfo::Make(kBmpSize,
  65. kBmpSize,
  66. (SkColorType)colorType,
  67. b ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
  68. if (!bmp->tryAllocPixels(info)) {
  69. SkDEBUGF("Bitmap not allocated\n");
  70. }
  71. SkColor c;
  72. fuzz->next(&c);
  73. bmp->eraseColor(c);
  74. fuzz->next(&b);
  75. SkPaint p;
  76. if (b) {
  77. init_paint(fuzz, &p);
  78. }
  79. else {
  80. fuzz->next(&c);
  81. p.setColor(c);
  82. }
  83. }
  84. static void init_surface(Fuzz* fuzz, sk_sp<SkSurface>* s) {
  85. uint8_t x, y;
  86. fuzz->nextRange(&x, 1, kMaxX);
  87. fuzz->nextRange(&y, 1, kMaxY);
  88. *s = SkSurface::MakeRasterN32Premul(x, y);
  89. if (!*s) {
  90. // Was possibly too big for the memory constrained fuzzing environments
  91. *s = SkSurface::MakeNull(x, y);
  92. }
  93. }
  94. static void fuzz_drawText(Fuzz* fuzz, sk_sp<SkTypeface> typeface) {
  95. SkFont font(typeface);
  96. SkPaint p;
  97. init_paint(fuzz, &p);
  98. sk_sp<SkSurface> surface;
  99. init_surface(fuzz, &surface);
  100. char text[kTxtLen];
  101. init_string(fuzz, text, kTxtLen);
  102. SkScalar x, y;
  103. fuzz->next(&x, &y);
  104. // populate pts array
  105. SkPoint pts[kPtsLen];
  106. for (uint8_t i = 0; i < kPtsLen; ++i) {
  107. pts[i].set(x, y);
  108. x += font.getSize();
  109. }
  110. bool b;
  111. fuzz->next(&b);
  112. font.setForceAutoHinting(b);
  113. fuzz->next(&b);
  114. font.setEmbeddedBitmaps(b);
  115. fuzz->next(&b);
  116. font.setEmbolden(b);
  117. fuzz->next(&b);
  118. font.setEdging(b ? SkFont::Edging::kAntiAlias : SkFont::Edging::kSubpixelAntiAlias);
  119. fuzz->next(&b);
  120. font.setLinearMetrics(b);
  121. fuzz->next(&b);
  122. font.setSubpixel(b);
  123. fuzz->next(&x);
  124. font.setScaleX(x);
  125. fuzz->next(&x);
  126. font.setSkewX(x);
  127. fuzz->next(&x);
  128. font.setSize(x);
  129. SkCanvas* cnv = surface->getCanvas();
  130. fuzz->next(&x);
  131. fuzz->next(&y);
  132. cnv->drawTextBlob(SkTextBlob::MakeFromPosText(text, kTxtLen-1, pts, font), x, y, p);
  133. }
  134. static void fuzz_drawCircle(Fuzz* fuzz) {
  135. SkPaint p;
  136. init_paint(fuzz, &p);
  137. sk_sp<SkSurface> surface;
  138. init_surface(fuzz, &surface);
  139. SkScalar a, b, c;
  140. fuzz->next(&a, &b, &c);
  141. surface->getCanvas()->drawCircle(a, b, c, p);
  142. }
  143. static void fuzz_drawLine(Fuzz* fuzz) {
  144. SkPaint p;
  145. init_paint(fuzz, &p);
  146. sk_sp<SkSurface> surface;
  147. init_surface(fuzz, &surface);
  148. SkScalar a, b, c, d;
  149. fuzz->next(&a, &b, &c, &d);
  150. surface->getCanvas()->drawLine(a, b, c, d, p);
  151. }
  152. static void fuzz_drawRect(Fuzz* fuzz) {
  153. SkPaint p;
  154. init_paint(fuzz, &p);
  155. sk_sp<SkSurface> surface;
  156. init_surface(fuzz, &surface);
  157. SkScalar a, b, c, d;
  158. fuzz->next(&a, &b, &c, &d);
  159. SkRect r;
  160. r = SkRect::MakeXYWH(a, b, c, d);
  161. SkCanvas* cnv = surface->getCanvas();
  162. cnv->drawRect(r, p);
  163. bool bl;
  164. fuzz->next(&bl);
  165. fuzz->next(&a, &b, &c, &d);
  166. r = SkRect::MakeXYWH(a, b, c, d);
  167. cnv->clipRect(r, kIntersect_SkClipOp, bl);
  168. }
  169. static void fuzz_drawPath(Fuzz* fuzz) {
  170. SkPaint p;
  171. init_paint(fuzz, &p);
  172. sk_sp<SkSurface> surface;
  173. init_surface(fuzz, &surface);
  174. // TODO(kjlubick): put the ability to fuzz a path in shared file, with
  175. // other common things (e.g. rects, lines)
  176. uint8_t i, j;
  177. fuzz->nextRange(&i, 0, 10); // set i to number of operations to perform
  178. SkPath path;
  179. SkScalar a, b, c, d, e, f;
  180. for (int k = 0; k < i; ++k) {
  181. fuzz->nextRange(&j, 0, 5); // set j to choose operation to perform
  182. switch (j) {
  183. case 0:
  184. fuzz->next(&a, &b);
  185. path.moveTo(a, b);
  186. break;
  187. case 1:
  188. fuzz->next(&a, &b);
  189. path.lineTo(a, b);
  190. break;
  191. case 2:
  192. fuzz->next(&a, &b, &c, &d);
  193. path.quadTo(a, b, c, d);
  194. break;
  195. case 3:
  196. fuzz->next(&a, &b, &c, &d, &e);
  197. path.conicTo(a, b, c, d, e);
  198. break;
  199. case 4:
  200. fuzz->next(&a, &b, &c, &d, &e, &f);
  201. path.cubicTo(a, b, c, d, e, f);
  202. break;
  203. case 5:
  204. fuzz->next(&a, &b, &c, &d, &e);
  205. path.arcTo(a, b, c, d, e);
  206. break;
  207. }
  208. }
  209. path.close();
  210. SkCanvas* cnv = surface->getCanvas();
  211. cnv->drawPath(path, p);
  212. bool bl;
  213. fuzz->next(&bl);
  214. cnv->clipPath(path, kIntersect_SkClipOp, bl);
  215. }
  216. static void fuzz_drawBitmap(Fuzz* fuzz) {
  217. SkPaint p;
  218. init_paint(fuzz, &p);
  219. sk_sp<SkSurface> surface;
  220. init_surface(fuzz, &surface);
  221. SkBitmap bmp;
  222. init_bitmap(fuzz, &bmp);
  223. SkScalar a, b;
  224. fuzz->next(&a, &b);
  225. surface->getCanvas()->drawBitmap(bmp, a, b, &p);
  226. }
  227. static void fuzz_drawImage(Fuzz* fuzz) {
  228. SkPaint p;
  229. init_paint(fuzz, &p);
  230. sk_sp<SkSurface> surface;
  231. init_surface(fuzz, &surface);
  232. SkBitmap bmp;
  233. init_bitmap(fuzz, &bmp);
  234. sk_sp<SkImage> image(SkImage::MakeFromBitmap(bmp));
  235. bool bl;
  236. fuzz->next(&bl);
  237. SkScalar a, b;
  238. fuzz->next(&a, &b);
  239. if (bl) {
  240. surface->getCanvas()->drawImage(image, a, b, &p);
  241. }
  242. else {
  243. SkRect dst = SkRect::MakeWH(a, b);
  244. fuzz->next(&a, &b);
  245. SkRect src = SkRect::MakeWH(a, b);
  246. uint8_t x;
  247. fuzz->nextRange(&x, 0, 1);
  248. SkCanvas::SrcRectConstraint cst = (SkCanvas::SrcRectConstraint)x;
  249. surface->getCanvas()->drawImageRect(image, src, dst, &p, cst);
  250. }
  251. }
  252. static void fuzz_drawPaint(Fuzz* fuzz) {
  253. SkPaint l, p;
  254. init_paint(fuzz, &p);
  255. sk_sp<SkSurface> surface;
  256. init_surface(fuzz, &surface);
  257. surface->getCanvas()->drawPaint(p);
  258. }
  259. DEF_FUZZ(DrawFunctions, fuzz) {
  260. uint8_t i;
  261. fuzz->next(&i);
  262. switch(i) {
  263. case 0: {
  264. sk_sp<SkTypeface> f = SkTypeface::MakeDefault();
  265. if (f == nullptr) {
  266. SkDebugf("Could not initialize font.\n");
  267. fuzz->signalBug();
  268. }
  269. SkDEBUGF("Fuzz DrawText\n");
  270. fuzz_drawText(fuzz, f);
  271. return;
  272. }
  273. case 1:
  274. SkDEBUGF("Fuzz DrawRect\n");
  275. fuzz_drawRect(fuzz);
  276. return;
  277. case 2:
  278. SkDEBUGF("Fuzz DrawCircle\n");
  279. fuzz_drawCircle(fuzz);
  280. return;
  281. case 3:
  282. SkDEBUGF("Fuzz DrawLine\n");
  283. fuzz_drawLine(fuzz);
  284. return;
  285. case 4:
  286. SkDEBUGF("Fuzz DrawPath\n");
  287. fuzz_drawPath(fuzz);
  288. return;
  289. case 5:
  290. SkDEBUGF("Fuzz DrawImage/DrawImageRect\n");
  291. fuzz_drawImage(fuzz);
  292. return;
  293. case 6:
  294. SkDEBUGF("Fuzz DrawBitmap\n");
  295. fuzz_drawBitmap(fuzz);
  296. return;
  297. case 7:
  298. SkDEBUGF("Fuzz DrawPaint\n");
  299. fuzz_drawPaint(fuzz);
  300. return;
  301. }
  302. }