@@ -58,13 +58,24 @@ namespace LV {
5858
5959 VideoPtr bitmap_load_png (std::istream& input)
6060 {
61- auto saved_stream_pos = input.tellg ();
61+ auto start_stream_pos = input.tellg ();
62+
63+ // Check PNG signature.
6264
6365 png_byte signature[8 ];
64- input.read (reinterpret_cast <char *> (signature), sizeof (signature));
66+ if (!input.read (reinterpret_cast <char *> (signature), sizeof (signature))) {
67+ input.clear ();
68+ input.seekg (start_stream_pos);
69+ return nullptr ;
70+ }
6571
6672 bool is_png = !png_sig_cmp (signature, 0 , sizeof (signature));
6773
74+ // Clean up test by rewinding to the beginning, like we have read nothing.
75+ if (!input.seekg (start_stream_pos)) {
76+ return nullptr ;
77+ }
78+
6879 if (!is_png) {
6980 return nullptr ;
7081 }
@@ -86,15 +97,22 @@ namespace LV {
8697 return nullptr ;
8798 }
8899
100+ // Read PNG image data
101+
102+ // Skip to the first chunk, which comes right after the signature.
103+ input.seekg (start_stream_pos + std::streampos {sizeof (signature)});
104+
89105 uint8_t * pixels = nullptr ;
90106 uint8_t ** pixel_row_ptrs = nullptr ;
91107
92108 if (setjmp (png_jmpbuf (png_ptr))) {
93- input.seekg (saved_stream_pos);
109+ // Some error happened during reading. Rewind to the beginning, like we have read nothing.
110+ input.clear ();
111+ input.seekg (start_stream_pos);
94112
95113 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
96114
97- delete [] pixel_row_ptrs;
115+ delete[] pixel_row_ptrs;
98116 visual_mem_free (pixels);
99117
100118 return nullptr ;
@@ -171,7 +189,7 @@ namespace LV {
171189
172190 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
173191
174- delete [] pixel_row_ptrs;
192+ delete[] pixel_row_ptrs;
175193
176194 return Video::wrap (pixels, true , width, height, depth);
177195 }
0 commit comments