| Index: Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
|
| diff --git a/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp b/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
|
| index 1a6724407b97f2f220026e263fbfe6f40b7e2bf8..45d7c9fe373a36e39e1be42cb0ea0868a8fdbb21 100644
|
| --- a/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
|
| +++ b/Source/platform/fonts/opentype/OpenTypeSanitizer.cpp
|
| @@ -35,22 +35,26 @@
|
| #include "platform/SharedBuffer.h"
|
| #include "opentype-sanitiser.h"
|
| #include "ots-memory-stream.h"
|
| +#include "third_party/brotli/src/woff2/woff2_dec.h"
|
| +#include "wtf/Vector.h"
|
|
|
| namespace blink {
|
|
|
| -PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize()
|
| -{
|
| - if (!m_buffer)
|
| - return nullptr;
|
| +// This is the largest web font size which we'll try to transcode.
|
| +static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB
|
|
|
| - // This is the largest web font size which we'll try to transcode.
|
| - static const size_t maxWebFontSize = 30 * 1024 * 1024; // 30 MB
|
| - if (m_buffer->size() > maxWebFontSize)
|
| - return nullptr;
|
| +static bool isWoff2(SharedBuffer* buffer)
|
| +{
|
| + static const size_t signatureSize = 4;
|
| + if (buffer->size() < signatureSize)
|
| + return false;
|
|
|
| - if (RuntimeEnabledFeatures::woff2Enabled())
|
| - ots::EnableWOFF2();
|
| + const char* signature = buffer->data();
|
| + return signature[0] == 'w' && signature[1] == 'O' && signature[2] == 'F' && signature[3] == '2';
|
| +}
|
|
|
| +static PassRefPtr<SharedBuffer> transcode(const uint8_t* targetData, size_t targetDataSize)
|
| +{
|
| // A transcoded font is usually smaller than an original font.
|
| // However, it can be slightly bigger than the original one due to
|
| // name table replacement and/or padding for glyf table.
|
| @@ -58,14 +62,40 @@ PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize()
|
| // With WOFF fonts, however, we'll be decompressing, so the result can be
|
| // much larger than the original.
|
|
|
| - ots::ExpandingMemoryStream output(m_buffer->size(), maxWebFontSize);
|
| - if (!ots::Process(&output, reinterpret_cast<const uint8_t*>(m_buffer->data()), m_buffer->size()))
|
| + ots::ExpandingMemoryStream output(targetDataSize, maxWebFontSize);
|
| + if (!ots::Process(&output, targetData, targetDataSize))
|
| return nullptr;
|
|
|
| const size_t transcodeLen = output.Tell();
|
| return SharedBuffer::create(static_cast<unsigned char*>(output.get()), transcodeLen);
|
| }
|
|
|
| +PassRefPtr<SharedBuffer> OpenTypeSanitizer::sanitize()
|
| +{
|
| + if (!m_buffer)
|
| + return nullptr;
|
| +
|
| + if (m_buffer->size() > maxWebFontSize)
|
| + return nullptr;
|
| +
|
| + if (RuntimeEnabledFeatures::woff2Enabled())
|
| + ots::EnableWOFF2();
|
| +
|
| + const uint8_t* originalData = reinterpret_cast<const uint8_t*>(m_buffer->data());
|
| + size_t originalDataSize = m_buffer->size();
|
| + if (RuntimeEnabledFeatures::woff2Enabled() && isWoff2(m_buffer)) {
|
| + size_t woff2Size = woff2::ComputeWOFF2FinalSize(originalData, originalDataSize);
|
| + if (woff2Size > maxWebFontSize)
|
| + return nullptr;
|
| +
|
| + Vector<uint8_t> woff2Output(woff2Size);
|
| + if (!woff2::ConvertWOFF2ToTTF(woff2Output.data(), woff2Size, originalData, originalDataSize))
|
| + return nullptr;
|
| + return transcode(woff2Output.data(), woff2Size);
|
| + }
|
| + return transcode(originalData, originalDataSize);
|
| +}
|
| +
|
| bool OpenTypeSanitizer::supportsFormat(const String& format)
|
| {
|
| return equalIgnoringCase(format, "woff")
|
|
|