mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 04:38:02 +00:00
Bug 1455848 - validate access to DWrite font files in WR and output helpful log messages on failure. r=jrmuizel
This commit is contained in:
parent
c13d380a26
commit
f7066e0fb7
@ -302,6 +302,23 @@ class Log {
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#ifdef WIN32
|
||||
Log& operator<<(const wchar_t aWStr[]) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
int wLen = (int)wcslen(aWStr);
|
||||
std::vector<char> str;
|
||||
int n = WideCharToMultiByte(0, 0, aWStr, wLen, nullptr, 0, nullptr,
|
||||
nullptr);
|
||||
if (n > 0) {
|
||||
std::vector<char> str(n+1);
|
||||
WideCharToMultiByte(0, 0, aWStr, wLen, str.data(), n+1, nullptr,
|
||||
nullptr);
|
||||
mMessage << str.data();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
Log& operator<<(bool aBool) {
|
||||
if (MOZ_UNLIKELY(LogIt())) {
|
||||
mMessage << (aBool ? "true" : "false");
|
||||
|
@ -385,6 +385,56 @@ bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Debugging kluge for bug 1455848. Remove once debugged!
|
||||
UINT32 numFiles;
|
||||
hr = mFontFace->GetFiles(&numFiles, nullptr);
|
||||
if (FAILED(hr) || !numFiles) {
|
||||
return false;
|
||||
}
|
||||
std::vector<RefPtr<IDWriteFontFile>> files;
|
||||
files.resize(numFiles);
|
||||
hr = mFontFace->GetFiles(&numFiles, getter_AddRefs(files[0]));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(familyName.size() >= 1 && familyName.back() == 0);
|
||||
for(auto& file : files) {
|
||||
const void* key;
|
||||
UINT32 keySize;
|
||||
hr = file->GetReferenceKey(&key, &keySize);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<IDWriteFontFileLoader> loader;
|
||||
hr = file->GetLoader(getter_AddRefs(loader));
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
RefPtr<IDWriteLocalFontFileLoader> localLoader;
|
||||
loader->QueryInterface(__uuidof(IDWriteLocalFontFileLoader), (void**)getter_AddRefs(localLoader));
|
||||
if (!localLoader) {
|
||||
return false;
|
||||
}
|
||||
UINT32 pathLen;
|
||||
hr = localLoader->GetFilePathLengthFromKey(key, keySize, &pathLen);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
size_t offset = familyName.size();
|
||||
familyName.resize(offset + pathLen + 1);
|
||||
hr = localLoader->GetFilePathFromKey(key, keySize, &familyName[offset], pathLen + 1);
|
||||
if (FAILED(hr)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(familyName.back() == 0);
|
||||
DWORD attribs = GetFileAttributesW(&familyName[offset]);
|
||||
if (attribs == INVALID_FILE_ATTRIBUTES) {
|
||||
gfxCriticalNote << "sending font family \"" << &familyName[0]
|
||||
<< "\" with invalid file \"" << &familyName[offset]
|
||||
<< "\"";
|
||||
}
|
||||
}
|
||||
|
||||
// The style information that identifies the font can be encoded easily in
|
||||
// less than 32 bits. Since the index is needed for font descriptors, only
|
||||
// the family name and style information, pass along the style in the index
|
||||
@ -392,7 +442,7 @@ bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
|
||||
// the data payload.
|
||||
uint32_t index = weight | (stretch << 16) | (style << 24);
|
||||
aCb(reinterpret_cast<const uint8_t*>(familyName.data()),
|
||||
(familyName.size() - 1) * sizeof(WCHAR), index, aBaton);
|
||||
familyName.size() * sizeof(WCHAR), index, aBaton);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,9 @@ parent:
|
||||
async FlushApzRepaints();
|
||||
sync GetAPZTestData() returns (APZTestData data);
|
||||
|
||||
// Debugging routine for bug 1455848.
|
||||
async ValidateFontDescriptor(uint8_t[] desc);
|
||||
|
||||
async Shutdown();
|
||||
sync ShutdownSync();
|
||||
child:
|
||||
|
@ -225,6 +225,14 @@ static void WriteFontDescriptor(const uint8_t* aData, uint32_t aLength,
|
||||
|
||||
*sink->mFontKey = sink->mWrBridge->GetNextFontKey();
|
||||
|
||||
#ifdef XP_WIN
|
||||
// FIXME: Debugging kluge for bug 1455848. Remove once debugged!
|
||||
nsTArray<uint8_t> data;
|
||||
data.AppendElements(aData, aLength);
|
||||
sink->mWrBridge->SendValidateFontDescriptor(data);
|
||||
aLength = uint32_t(wcsnlen_s((const wchar_t*)aData, aLength / sizeof(wchar_t)) * sizeof(wchar_t));
|
||||
#endif
|
||||
|
||||
sink->mResources->AddFontDescriptor(
|
||||
*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength),
|
||||
aIndex);
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
#include "mozilla/widget/CompositorWidget.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "dwrite.h"
|
||||
#endif
|
||||
|
||||
using mozilla::Telemetry::LABELS_CONTENT_FRAME_TIME_REASON;
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
@ -697,6 +701,48 @@ void WebRenderBridgeParent::ObserveSharedSurfaceRelease(
|
||||
}
|
||||
}
|
||||
|
||||
// Debugging kluge for bug 1455848. Remove once debugged!
|
||||
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvValidateFontDescriptor(
|
||||
nsTArray<uint8_t>&& aData) {
|
||||
if (mDestroyed) {
|
||||
return IPC_OK();
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
nsTArray<uint8_t> data(aData);
|
||||
wchar_t* family = (wchar_t*)data.Elements();
|
||||
size_t remaining = data.Length() / sizeof(wchar_t);
|
||||
size_t familyLength = wcsnlen_s(family, remaining);
|
||||
MOZ_ASSERT(familyLength < remaining && family[familyLength] == 0);
|
||||
remaining -= familyLength + 1;
|
||||
wchar_t* files = family + familyLength + 1;
|
||||
BOOL exists = FALSE;
|
||||
if (RefPtr<IDWriteFontCollection> systemFonts = Factory::GetDWriteSystemFonts()) {
|
||||
UINT32 idx;
|
||||
systemFonts->FindFamilyName(family, &idx, &exists);
|
||||
}
|
||||
if (!remaining) {
|
||||
gfxCriticalNote << (exists ? "found" : "MISSING")
|
||||
<< " font family \"" << family
|
||||
<< "\" has no files!";
|
||||
}
|
||||
while (remaining > 0) {
|
||||
size_t fileLength = wcsnlen_s(files, remaining);
|
||||
MOZ_ASSERT(fileLength < remaining && files[fileLength] == 0);
|
||||
DWORD attribs = GetFileAttributesW(files);
|
||||
if (!exists || attribs == INVALID_FILE_ATTRIBUTES) {
|
||||
gfxCriticalNote << (exists ? "found" : "MISSING")
|
||||
<< " font family \"" << family
|
||||
<< "\" has " << (attribs == INVALID_FILE_ATTRIBUTES ? "INVALID" : "valid")
|
||||
<< " file \"" << files
|
||||
<< "\"";
|
||||
}
|
||||
remaining -= fileLength + 1;
|
||||
files += fileLength + 1;
|
||||
}
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(
|
||||
nsTArray<OpUpdateResource>&& aResourceUpdates,
|
||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||
|
@ -123,6 +123,9 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
||||
nsTArray<WebRenderParentCommand>&& commands) override;
|
||||
mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvValidateFontDescriptor(
|
||||
nsTArray<uint8_t>&& aData) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
|
||||
const LayersObserverEpoch& aChildEpoch) override;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user