Permalink
Browse files

Catch and throw PNG exceptions - fixes #1213

The png library uses setjmp/longjmp to throw exceptions when reading. If this
is not set up, the png library calls abort(). This change handles the errors
and throws a C++ exception instead.

This issue was found by testing images from pngsuite at
http://www.schaik.com/pngsuite/. These images are included and a unit test was
added to test both images that should be successful and images that should
throw an exception.
  • Loading branch information...
1 parent 291bc9b commit cd7ad3e15eed5b9b582c2b92175a68b77c1f5547 Carl Simonson committed with simonsonc Jun 4, 2012
Showing with 83 additions and 0 deletions.
  1. +14 −0 src/png_reader.cpp
  2. +9 −0 tests/data/pngsuite/PngSuite.LICENSE
  3. +25 −0 tests/data/pngsuite/PngSuite.README
  4. BIN tests/data/pngsuite/PngSuite.png
  5. BIN tests/data/pngsuite/basi0g01.png
  6. BIN tests/data/pngsuite/basi0g02.png
  7. BIN tests/data/pngsuite/basi0g04.png
  8. BIN tests/data/pngsuite/basi0g08.png
  9. BIN tests/data/pngsuite/basi0g16.png
  10. BIN tests/data/pngsuite/basi2c08.png
  11. BIN tests/data/pngsuite/basi2c16.png
  12. BIN tests/data/pngsuite/basi3p01.png
  13. BIN tests/data/pngsuite/basi3p02.png
  14. BIN tests/data/pngsuite/basi3p04.png
  15. BIN tests/data/pngsuite/basi3p08.png
  16. BIN tests/data/pngsuite/basi4a08.png
  17. BIN tests/data/pngsuite/basi4a16.png
  18. BIN tests/data/pngsuite/basi6a08.png
  19. BIN tests/data/pngsuite/basi6a16.png
  20. BIN tests/data/pngsuite/basn0g01.png
  21. BIN tests/data/pngsuite/basn0g02.png
  22. BIN tests/data/pngsuite/basn0g04.png
  23. BIN tests/data/pngsuite/basn0g08.png
  24. BIN tests/data/pngsuite/basn0g16.png
  25. BIN tests/data/pngsuite/basn2c08.png
  26. BIN tests/data/pngsuite/basn2c16.png
  27. BIN tests/data/pngsuite/basn3p01.png
  28. BIN tests/data/pngsuite/basn3p02.png
  29. BIN tests/data/pngsuite/basn3p04.png
  30. BIN tests/data/pngsuite/basn3p08.png
  31. BIN tests/data/pngsuite/basn4a08.png
  32. BIN tests/data/pngsuite/basn4a16.png
  33. BIN tests/data/pngsuite/basn6a08.png
  34. BIN tests/data/pngsuite/basn6a16.png
  35. BIN tests/data/pngsuite/bgai4a08.png
  36. BIN tests/data/pngsuite/bgai4a16.png
  37. BIN tests/data/pngsuite/bgan6a08.png
  38. BIN tests/data/pngsuite/bgan6a16.png
  39. BIN tests/data/pngsuite/bgbn4a08.png
  40. BIN tests/data/pngsuite/bggn4a16.png
  41. BIN tests/data/pngsuite/bgwn6a08.png
  42. BIN tests/data/pngsuite/bgyn6a16.png
  43. BIN tests/data/pngsuite/ccwn2c08.png
  44. BIN tests/data/pngsuite/ccwn3p08.png
  45. BIN tests/data/pngsuite/cdfn2c08.png
  46. BIN tests/data/pngsuite/cdhn2c08.png
  47. BIN tests/data/pngsuite/cdsn2c08.png
  48. BIN tests/data/pngsuite/cdun2c08.png
  49. BIN tests/data/pngsuite/ch1n3p04.png
  50. BIN tests/data/pngsuite/ch2n3p08.png
  51. BIN tests/data/pngsuite/cm0n0g04.png
  52. BIN tests/data/pngsuite/cm7n0g04.png
  53. BIN tests/data/pngsuite/cm9n0g04.png
  54. BIN tests/data/pngsuite/cs3n2c16.png
  55. BIN tests/data/pngsuite/cs3n3p08.png
  56. BIN tests/data/pngsuite/cs5n2c08.png
  57. BIN tests/data/pngsuite/cs5n3p08.png
  58. BIN tests/data/pngsuite/cs8n2c08.png
  59. BIN tests/data/pngsuite/cs8n3p08.png
  60. BIN tests/data/pngsuite/ct0n0g04.png
  61. BIN tests/data/pngsuite/ct1n0g04.png
  62. BIN tests/data/pngsuite/cten0g04.png
  63. BIN tests/data/pngsuite/ctfn0g04.png
  64. BIN tests/data/pngsuite/ctgn0g04.png
  65. BIN tests/data/pngsuite/cthn0g04.png
  66. BIN tests/data/pngsuite/ctjn0g04.png
  67. BIN tests/data/pngsuite/ctzn0g04.png
  68. BIN tests/data/pngsuite/f00n0g08.png
  69. BIN tests/data/pngsuite/f00n2c08.png
  70. BIN tests/data/pngsuite/f01n0g08.png
  71. BIN tests/data/pngsuite/f01n2c08.png
  72. BIN tests/data/pngsuite/f02n0g08.png
  73. BIN tests/data/pngsuite/f02n2c08.png
  74. BIN tests/data/pngsuite/f03n0g08.png
  75. BIN tests/data/pngsuite/f03n2c08.png
  76. BIN tests/data/pngsuite/f04n0g08.png
  77. BIN tests/data/pngsuite/f04n2c08.png
  78. BIN tests/data/pngsuite/f99n0g04.png
  79. BIN tests/data/pngsuite/g03n0g16.png
  80. BIN tests/data/pngsuite/g03n2c08.png
  81. BIN tests/data/pngsuite/g03n3p04.png
  82. BIN tests/data/pngsuite/g04n0g16.png
  83. BIN tests/data/pngsuite/g04n2c08.png
  84. BIN tests/data/pngsuite/g04n3p04.png
  85. BIN tests/data/pngsuite/g05n0g16.png
  86. BIN tests/data/pngsuite/g05n2c08.png
  87. BIN tests/data/pngsuite/g05n3p04.png
  88. BIN tests/data/pngsuite/g07n0g16.png
  89. BIN tests/data/pngsuite/g07n2c08.png
  90. BIN tests/data/pngsuite/g07n3p04.png
  91. BIN tests/data/pngsuite/g10n0g16.png
  92. BIN tests/data/pngsuite/g10n2c08.png
  93. BIN tests/data/pngsuite/g10n3p04.png
  94. BIN tests/data/pngsuite/g25n0g16.png
  95. BIN tests/data/pngsuite/g25n2c08.png
  96. BIN tests/data/pngsuite/g25n3p04.png
  97. BIN tests/data/pngsuite/oi1n0g16.png
  98. BIN tests/data/pngsuite/oi1n2c16.png
  99. BIN tests/data/pngsuite/oi2n0g16.png
  100. BIN tests/data/pngsuite/oi2n2c16.png
  101. BIN tests/data/pngsuite/oi4n0g16.png
  102. BIN tests/data/pngsuite/oi4n2c16.png
  103. BIN tests/data/pngsuite/oi9n0g16.png
  104. BIN tests/data/pngsuite/oi9n2c16.png
  105. BIN tests/data/pngsuite/pp0n2c16.png
  106. BIN tests/data/pngsuite/pp0n6a08.png
  107. BIN tests/data/pngsuite/ps1n0g08.png
  108. BIN tests/data/pngsuite/ps1n2c16.png
  109. BIN tests/data/pngsuite/ps2n0g08.png
  110. BIN tests/data/pngsuite/ps2n2c16.png
  111. BIN tests/data/pngsuite/s01i3p01.png
  112. BIN tests/data/pngsuite/s01n3p01.png
  113. BIN tests/data/pngsuite/s02i3p01.png
  114. BIN tests/data/pngsuite/s02n3p01.png
  115. BIN tests/data/pngsuite/s03i3p01.png
  116. BIN tests/data/pngsuite/s03n3p01.png
  117. BIN tests/data/pngsuite/s04i3p01.png
  118. BIN tests/data/pngsuite/s04n3p01.png
  119. BIN tests/data/pngsuite/s05i3p02.png
  120. BIN tests/data/pngsuite/s05n3p02.png
  121. BIN tests/data/pngsuite/s06i3p02.png
  122. BIN tests/data/pngsuite/s06n3p02.png
  123. BIN tests/data/pngsuite/s07i3p02.png
  124. BIN tests/data/pngsuite/s07n3p02.png
  125. BIN tests/data/pngsuite/s08i3p02.png
  126. BIN tests/data/pngsuite/s08n3p02.png
  127. BIN tests/data/pngsuite/s09i3p02.png
  128. BIN tests/data/pngsuite/s09n3p02.png
  129. BIN tests/data/pngsuite/s32i3p04.png
  130. BIN tests/data/pngsuite/s32n3p04.png
  131. BIN tests/data/pngsuite/s33i3p04.png
  132. BIN tests/data/pngsuite/s33n3p04.png
  133. BIN tests/data/pngsuite/s34i3p04.png
  134. BIN tests/data/pngsuite/s34n3p04.png
  135. BIN tests/data/pngsuite/s35i3p04.png
  136. BIN tests/data/pngsuite/s35n3p04.png
  137. BIN tests/data/pngsuite/s36i3p04.png
  138. BIN tests/data/pngsuite/s36n3p04.png
  139. BIN tests/data/pngsuite/s37i3p04.png
  140. BIN tests/data/pngsuite/s37n3p04.png
  141. BIN tests/data/pngsuite/s38i3p04.png
  142. BIN tests/data/pngsuite/s38n3p04.png
  143. BIN tests/data/pngsuite/s39i3p04.png
  144. BIN tests/data/pngsuite/s39n3p04.png
  145. BIN tests/data/pngsuite/s40i3p04.png
  146. BIN tests/data/pngsuite/s40n3p04.png
  147. BIN tests/data/pngsuite/tbbn0g04.png
  148. BIN tests/data/pngsuite/tbbn2c16.png
  149. BIN tests/data/pngsuite/tbbn3p08.png
  150. BIN tests/data/pngsuite/tbgn2c16.png
  151. BIN tests/data/pngsuite/tbgn3p08.png
  152. BIN tests/data/pngsuite/tbrn2c08.png
  153. BIN tests/data/pngsuite/tbwn0g16.png
  154. BIN tests/data/pngsuite/tbwn3p08.png
  155. BIN tests/data/pngsuite/tbyn3p08.png
  156. BIN tests/data/pngsuite/tp0n0g08.png
  157. BIN tests/data/pngsuite/tp0n2c08.png
  158. BIN tests/data/pngsuite/tp0n3p08.png
  159. BIN tests/data/pngsuite/tp1n3p08.png
  160. BIN tests/data/pngsuite/xc1n0g08.png
  161. BIN tests/data/pngsuite/xc9n2c08.png
  162. BIN tests/data/pngsuite/xcrn0g04.png
  163. BIN tests/data/pngsuite/xcsn0g01.png
  164. BIN tests/data/pngsuite/xd0n2c08.png
  165. BIN tests/data/pngsuite/xd3n2c08.png
  166. BIN tests/data/pngsuite/xd9n2c08.png
  167. BIN tests/data/pngsuite/xdtn0g01.png
  168. BIN tests/data/pngsuite/xhdn0g08.png
  169. BIN tests/data/pngsuite/xlfn0g04.png
  170. BIN tests/data/pngsuite/xs1n0g01.png
  171. BIN tests/data/pngsuite/xs2n0g01.png
  172. BIN tests/data/pngsuite/xs4n0g01.png
  173. BIN tests/data/pngsuite/xs7n0g01.png
  174. BIN tests/data/pngsuite/z00n2c08.png
  175. BIN tests/data/pngsuite/z03n2c08.png
  176. BIN tests/data/pngsuite/z06n2c08.png
  177. BIN tests/data/pngsuite/z09n2c08.png
  178. +35 −0 tests/python_tests/pngsuite_test.py
View
@@ -119,6 +119,13 @@ void png_reader::init()
throw image_reader_exception("failed to create info_ptr");
}
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr,0,0);
+ fclose(fp);
+ throw image_reader_exception("failed to read");
+ }
+
png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);
png_set_sig_bytes(png_ptr,8);
@@ -168,6 +175,13 @@ void png_reader::read(unsigned x0, unsigned y0,image_data_32& image)
throw image_reader_exception("failed to create info_ptr");
}
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr,0,0);
+ fclose(fp);
+ throw image_reader_exception("failed to read");
+ }
+
png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data);
png_read_info(png_ptr, info_ptr);
@@ -0,0 +1,9 @@
+PngSuite
+--------
+
+Permission to use, copy, modify and distribute these images for any
+purpose and without fee is hereby granted.
+
+
+(c) Willem van Schaik, 1996, 2011
+
@@ -0,0 +1,25 @@
+ PNGSUITE
+----------------
+
+ testset for PNG-(de)coders
+ created by Willem van Schaik
+------------------------------------
+
+This is a collection of graphics images created to test the png applications
+like viewers, converters and editors. All (as far as that is possible)
+formats supported by the PNG standard are represented.
+
+The suite consists of the following files:
+
+- PngSuite.README - this file
+- PngSuite.LICENSE - the PngSuite is freeware
+- PngSuite.png - image with PngSuite logo
+- PngSuite.tgz - archive of all PNG testfiles
+- PngSuite.zip - same in .zip format for PCs
+
+
+--------
+ (c) Willem van Schaik
+ willem@schaik.com
+ Calgary, April 2011
+
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+import os
+import mapnik
+from nose.tools import *
+from utilities import execution_path
+
+datadir = '../data/pngsuite'
+
+def setup():
+ # All of the paths used are relative, if we run the tests
+ # from another directory we need to chdir()
+ os.chdir(execution_path('.'))
+
+def assert_broken_file(fname):
+ assert_raises(RuntimeError, lambda: mapnik.Image.open(fname))
+
+def assert_good_file(fname):
+ assert mapnik.Image.open(fname)
+
+def get_pngs(good):
+ files = [ x for x in os.listdir(datadir) if x.endswith('.png') ]
+ return [ os.path.join(datadir, x) for x in files if good != x.startswith('x') ]
+
+def test_good_pngs():
+ for x in get_pngs(True):
+ yield assert_good_file, x
+
+def test_broken_pngs():
+ for x in get_pngs(False):
+ yield assert_broken_file, x
+
+if __name__ == "__main__":
+ setup()
+ [eval(run)() for run in dir() if 'test_' in run]

0 comments on commit cd7ad3e

Please sign in to comment.