Index: ui/base/resource/resource_bundle.cc |
diff --git a/ui/base/resource/resource_bundle.cc b/ui/base/resource/resource_bundle.cc |
index daab4db206f9ab86e0bfbdac730c606b2af9121a..06951c8bc7ae7e33b310566769f7f2a44a198d18 100644 |
--- a/ui/base/resource/resource_bundle.cc |
+++ b/ui/base/resource/resource_bundle.cc |
@@ -23,10 +23,12 @@ |
#include "base/strings/string_piece.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/synchronization/lock.h" |
+#include "base/sys_byteorder.h" |
#include "build/build_config.h" |
#include "skia/ext/image_operations.h" |
#include "third_party/skia/include/core/SkBitmap.h" |
#include "third_party/skia/include/core/SkColor.h" |
+#include "third_party/zlib/zlib.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/base/layout.h" |
#include "ui/base/material_design/material_design_controller.h" |
@@ -112,6 +114,33 @@ SkBitmap CreateEmptyBitmap() { |
return bitmap; |
} |
+// Decodes given gzip input via zlib. |
+base::RefCountedBytes* DecodeGzipData( |
+ const unsigned char* input_buffer, |
+ size_t input_size) { |
+ z_stream infstream; |
+ infstream.zalloc = Z_NULL; |
+ infstream.zfree = Z_NULL; |
+ infstream.opaque = Z_NULL; |
+ |
+ infstream.avail_in = input_size; |
+ infstream.next_in = const_cast<Bytef*>(input_buffer); |
+ |
+ // Size of output comes from footer of gzip file format, found as the last 4 |
+ // bytes in the compressed file, which are stored little endian. |
+ infstream.avail_out = base::ByteSwapToLE32( |
+ *reinterpret_cast<const uint32_t*>(&input_buffer[input_size - 4])); |
+ |
+ std::vector<unsigned char> output(infstream.avail_out); |
+ infstream.next_out = reinterpret_cast<Bytef*>(&output[0]); // output buffer |
+ |
+ CHECK(inflateInit2(&infstream, 16) == Z_OK); |
+ CHECK(inflate(&infstream, Z_FINISH) == Z_STREAM_END); |
+ CHECK(inflateEnd(&infstream) == Z_OK); |
+ |
+ return new base::RefCountedBytes(output); |
flackr
2016/05/27 19:42:15
I don't think this is actually going to be cleaned
smaier
2016/05/27 21:20:26
Agreed, but this is the interface of LoadDataResou
flackr
2016/05/30 18:55:33
Understood, but we've also only dealt with static
flackr
2016/05/30 20:23:47
Sorry about this, I misunderstood how the returned
|
+} |
+ |
} // namespace |
// An ImageSkiaSource that loads bitmaps for the requested scale factor from |
@@ -454,9 +483,16 @@ base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale( |
if (!bytes) { |
base::StringPiece data = |
- GetRawDataResourceForScale(resource_id, scale_factor); |
+ DoGetRawDataResourceForScale(resource_id, scale_factor); |
if (!data.empty()) { |
- bytes = new base::RefCountedStaticMemory(data.data(), data.length()); |
+ if (data.starts_with(CUSTOM_GZIP_HEADER)) { |
+ // Jump past special identification byte prepended to header |
+ const unsigned char* gzip_start = |
+ reinterpret_cast<const unsigned char*>(data.data()) + 1; |
+ bytes = DecodeGzipData(gzip_start, data.length() - 1); |
+ } else { |
+ bytes = new base::RefCountedStaticMemory(data.data(), data.length()); |
+ } |
} |
} |
@@ -470,6 +506,18 @@ base::StringPiece ResourceBundle::GetRawDataResource(int resource_id) const { |
base::StringPiece ResourceBundle::GetRawDataResourceForScale( |
int resource_id, |
ScaleFactor scale_factor) const { |
+ base::StringPiece data = |
+ DoGetRawDataResourceForScale(resource_id, scale_factor); |
+ |
+ // Do not allow this function to retrieve gzip compressed resources. |
+ CHECK(!data.starts_with(CUSTOM_GZIP_HEADER)); |
+ |
+ return data; |
+} |
+ |
+base::StringPiece ResourceBundle::DoGetRawDataResourceForScale( |
+ int resource_id, |
+ ScaleFactor scale_factor) const { |
base::StringPiece data; |
if (delegate_ && |
delegate_->GetRawDataResource(resource_id, scale_factor, &data)) |