Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Unified Diff: ui/gfx/codec/png_codec.cc

Issue 2576823002: Fix stack-use-after-scope in png_codec. (Closed)
Patch Set: BuildPNGStruct -> PngReadStructInfo::Build Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/codec/png_codec.cc
diff --git a/ui/gfx/codec/png_codec.cc b/ui/gfx/codec/png_codec.cc
index ac386ad91d0b656e146776c8077694c881719e99..7f0a569d7892e09eac7219d2449a5e85ac7ec52d 100644
--- a/ui/gfx/codec/png_codec.cc
+++ b/ui/gfx/codec/png_codec.cc
@@ -313,60 +313,56 @@ void DecodeEndCallback(png_struct* png_ptr, png_info* info) {
state->done = true;
}
-// Automatically destroys the given read structs on destruction to make
-// cleanup and error handling code cleaner.
-class PngReadStructDestroyer {
+// Holds png struct and info ensuring the proper destruction.
+class PngReadStructInfo {
public:
- PngReadStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {
+ PngReadStructInfo(): png_ptr_(nullptr), info_ptr_(nullptr) {
}
- ~PngReadStructDestroyer() {
- png_destroy_read_struct(ps_, pi_, NULL);
+ ~PngReadStructInfo() {
+ png_destroy_read_struct(&png_ptr_, &info_ptr_, NULL);
}
- private:
- png_struct** ps_;
- png_info** pi_;
- DISALLOW_COPY_AND_ASSIGN(PngReadStructDestroyer);
-};
-// Automatically destroys the given write structs on destruction to make
-// cleanup and error handling code cleaner.
-class PngWriteStructDestroyer {
- public:
- explicit PngWriteStructDestroyer(png_struct** ps) : ps_(ps), pi_(0) {
- }
- ~PngWriteStructDestroyer() {
- png_destroy_write_struct(ps_, pi_);
- }
- void SetInfoStruct(png_info** pi) {
- pi_ = pi;
+ bool Build(const unsigned char* input, size_t input_size) {
+ if (input_size < 8)
+ return false; // Input data too small to be a png
+
+ // Have libpng check the signature, it likes the first 8 bytes.
+ if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0)
+ return false;
+
+ png_ptr_ = png_create_read_struct(
+ PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr_)
+ return false;
+
+ info_ptr_ = png_create_info_struct(png_ptr_);
+ if (!info_ptr_) {
+ return false;
+ }
+ return true;
}
+
+ png_struct* png_ptr_;
+ png_info* info_ptr_;
private:
- png_struct** ps_;
- png_info** pi_;
- DISALLOW_COPY_AND_ASSIGN(PngWriteStructDestroyer);
+ DISALLOW_COPY_AND_ASSIGN(PngReadStructInfo);
};
-bool BuildPNGStruct(const unsigned char* input, size_t input_size,
- png_struct** png_ptr, png_info** info_ptr) {
- if (input_size < 8)
- return false; // Input data too small to be a png
-
- // Have libpng check the signature, it likes the first 8 bytes.
- if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0)
- return false;
-
- *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!*png_ptr)
- return false;
+// Holds png struct and info ensuring the proper destruction.
+class PngWriteStructInfo {
+ public:
+ PngWriteStructInfo() : png_ptr_(nullptr), info_ptr_(nullptr) {
+ }
- *info_ptr = png_create_info_struct(*png_ptr);
- if (!*info_ptr) {
- png_destroy_read_struct(png_ptr, NULL, NULL);
- return false;
+ ~PngWriteStructInfo() {
+ png_destroy_write_struct(&png_ptr_, &info_ptr_);
}
- return true;
-}
+ png_struct* png_ptr_;
+ png_info* info_ptr_;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PngWriteStructInfo);
+};
// Libpng user error and warning functions which allows us to print libpng
// errors and warnings using Chrome's logging facilities instead of stderr.
@@ -395,13 +391,11 @@ void LogLibPNGEncodeWarning(png_structp png_ptr, png_const_charp warning_msg) {
bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
ColorFormat format, std::vector<unsigned char>* output,
int* w, int* h) {
- png_struct* png_ptr = NULL;
- png_info* info_ptr = NULL;
- if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
+ PngReadStructInfo si;
+ if (!si.Build(input, input_size))
return false;
- PngReadStructDestroyer destroyer(&png_ptr, &info_ptr);
- if (setjmp(png_jmpbuf(png_ptr))) {
+ if (setjmp(png_jmpbuf(si.png_ptr_))) {
// The destroyer will ensure that the structures are cleaned up in this
// case, even though we may get here as a jump from random parts of the
// PNG library called below.
@@ -410,11 +404,12 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
PngDecoderState state(format, output);
- png_set_error_fn(png_ptr, NULL, LogLibPNGDecodeError, LogLibPNGDecodeWarning);
- png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
+ png_set_error_fn(si.png_ptr_, NULL,
+ LogLibPNGDecodeError, LogLibPNGDecodeWarning);
+ png_set_progressive_read_fn(si.png_ptr_, &state, &DecodeInfoCallback,
&DecodeRowCallback, &DecodeEndCallback);
- png_process_data(png_ptr,
- info_ptr,
+ png_process_data(si.png_ptr_,
+ si.info_ptr_,
const_cast<unsigned char*>(input),
input_size);
@@ -434,13 +429,11 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
SkBitmap* bitmap) {
DCHECK(bitmap);
- png_struct* png_ptr = NULL;
- png_info* info_ptr = NULL;
- if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr))
+ PngReadStructInfo si;
+ if (!si.Build(input, input_size))
return false;
- PngReadStructDestroyer destroyer(&png_ptr, &info_ptr);
- if (setjmp(png_jmpbuf(png_ptr))) {
+ if (setjmp(png_jmpbuf(si.png_ptr_))) {
// The destroyer will ensure that the structures are cleaned up in this
// case, even though we may get here as a jump from random parts of the
// PNG library called below.
@@ -449,10 +442,10 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size,
PngDecoderState state(bitmap);
- png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback,
+ png_set_progressive_read_fn(si.png_ptr_, &state, &DecodeInfoCallback,
&DecodeRowCallback, &DecodeEndCallback);
- png_process_data(png_ptr,
- info_ptr,
+ png_process_data(si.png_ptr_,
+ si.info_ptr_,
const_cast<unsigned char*>(input),
input_size);
@@ -708,20 +701,20 @@ bool EncodeWithCompressionLevel(const unsigned char* input,
// Row stride should be at least as long as the length of the data.
DCHECK(input_color_components * size.width() <= row_byte_width);
- png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, NULL, NULL);
- if (!png_ptr)
+ PngWriteStructInfo si;
+ si.png_ptr_ = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ NULL, NULL, NULL);
+ if (!si.png_ptr_)
return false;
- PngWriteStructDestroyer destroyer(&png_ptr);
- png_info* info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr)
+
+ si.info_ptr_ = png_create_info_struct(si.png_ptr_);
+ if (!si.info_ptr_)
return false;
- destroyer.SetInfoStruct(&info_ptr);
output->clear();
PngEncoderState state(output);
- bool success = DoLibpngWrite(png_ptr, info_ptr, &state,
+ bool success = DoLibpngWrite(si.png_ptr_, si.info_ptr_, &state,
size.width(), size.height(), row_byte_width,
input, compression_level, png_output_color_type,
output_color_components, converter, comments);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698