summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/gfxSVGGlyphs.cpp
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-05-23 19:47:59 -0400
committerGaming4JC <g4jc@hyperbola.info>2019-05-23 19:47:59 -0400
commit73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850 (patch)
tree5d1337e6614872da0c5fc28f4232852598cc98d3 /gfx/thebes/gfxSVGGlyphs.cpp
parent372fccddf49146f9a0847564959d36ba3bef2e62 (diff)
downloadUXP-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.tar
UXP-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.tar.gz
UXP-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.tar.lz
UXP-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.tar.xz
UXP-73f9b2c70d4653fb47c7f60d6c11aa26a0c0b850.zip
Issue #1101 - Support gzip-compressed SVGs in OpenType+SVG fonts
Diffstat (limited to 'gfx/thebes/gfxSVGGlyphs.cpp')
-rw-r--r--gfx/thebes/gfxSVGGlyphs.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/gfx/thebes/gfxSVGGlyphs.cpp b/gfx/thebes/gfxSVGGlyphs.cpp
index a7615eca8..23f68f590 100644
--- a/gfx/thebes/gfxSVGGlyphs.cpp
+++ b/gfx/thebes/gfxSVGGlyphs.cpp
@@ -31,6 +31,7 @@
#include "nsSMILAnimationController.h"
#include "gfxContext.h"
#include "harfbuzz/hb.h"
+#include "zlib.h"
#include "mozilla/dom/ImageTracker.h"
#define SVG_CONTENT_TYPE NS_LITERAL_CSTRING("image/svg+xml")
@@ -285,7 +286,44 @@ gfxSVGGlyphsDocument::gfxSVGGlyphsDocument(const uint8_t *aBuffer,
gfxSVGGlyphs *aSVGGlyphs)
: mOwner(aSVGGlyphs)
{
+ if (aBufLen >= 14 && aBuffer[0] == 31 && aBuffer[1] == 139) {
+ // It's a gzip-compressed document; decompress it before parsing.
+ // The original length (modulo 2^32) is found in the last 4 bytes
+ // of the data, stored in little-endian format. We read it as
+ // individual bytes to avoid possible alignment issues.
+ // (Note that if the original length was >2^32, then origLen here
+ // will be incorrect; but then the inflate() call will not return
+ // Z_STREAM_END and we'll bail out safely.)
+ size_t origLen = (size_t(aBuffer[aBufLen - 1]) << 24) +
+ (size_t(aBuffer[aBufLen - 2]) << 16) +
+ (size_t(aBuffer[aBufLen - 3]) << 8) +
+ size_t(aBuffer[aBufLen - 4]);
+ AutoTArray<uint8_t, 4096> outBuf;
+ if (outBuf.SetLength(origLen, mozilla::fallible)) {
+ z_stream s = {0};
+ s.next_in = const_cast<Byte*>(aBuffer);
+ s.avail_in = aBufLen;
+ s.next_out = outBuf.Elements();
+ s.avail_out = outBuf.Length();
+ // The magic number 16 here is the zlib flag to expect gzip format,
+ // see http://www.zlib.net/manual.html#Advanced
+ if (Z_OK == inflateInit2(&s, 16 + MAX_WBITS)) {
+ int result = inflate(&s, Z_FINISH);
+ if (Z_STREAM_END == result) {
+ MOZ_ASSERT(size_t(s.next_out - outBuf.Elements()) == origLen);
+ ParseDocument(outBuf.Elements(), outBuf.Length());
+ } else {
+ NS_WARNING("Failed to decompress SVG glyphs document");
+ }
+ inflateEnd(&s);
+ }
+ } else {
+ NS_WARNING("Failed to allocate memory for SVG glyphs document");
+ }
+ } else {
ParseDocument(aBuffer, aBufLen);
+ }
+
if (!mDocument) {
NS_WARNING("Could not parse SVG glyphs document");
return;