mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +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;
|
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) {
|
Log& operator<<(bool aBool) {
|
||||||
if (MOZ_UNLIKELY(LogIt())) {
|
if (MOZ_UNLIKELY(LogIt())) {
|
||||||
mMessage << (aBool ? "true" : "false");
|
mMessage << (aBool ? "true" : "false");
|
||||||
|
@ -385,6 +385,56 @@ bool UnscaledFontDWrite::GetWRFontDescriptor(WRFontDescriptorOutput aCb,
|
|||||||
return false;
|
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
|
// 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
|
// 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
|
// 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.
|
// the data payload.
|
||||||
uint32_t index = weight | (stretch << 16) | (style << 24);
|
uint32_t index = weight | (stretch << 16) | (style << 24);
|
||||||
aCb(reinterpret_cast<const uint8_t*>(familyName.data()),
|
aCb(reinterpret_cast<const uint8_t*>(familyName.data()),
|
||||||
(familyName.size() - 1) * sizeof(WCHAR), index, aBaton);
|
familyName.size() * sizeof(WCHAR), index, aBaton);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,9 @@ parent:
|
|||||||
async FlushApzRepaints();
|
async FlushApzRepaints();
|
||||||
sync GetAPZTestData() returns (APZTestData data);
|
sync GetAPZTestData() returns (APZTestData data);
|
||||||
|
|
||||||
|
// Debugging routine for bug 1455848.
|
||||||
|
async ValidateFontDescriptor(uint8_t[] desc);
|
||||||
|
|
||||||
async Shutdown();
|
async Shutdown();
|
||||||
sync ShutdownSync();
|
sync ShutdownSync();
|
||||||
child:
|
child:
|
||||||
|
@ -225,6 +225,14 @@ static void WriteFontDescriptor(const uint8_t* aData, uint32_t aLength,
|
|||||||
|
|
||||||
*sink->mFontKey = sink->mWrBridge->GetNextFontKey();
|
*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->mResources->AddFontDescriptor(
|
||||||
*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength),
|
*sink->mFontKey, Range<uint8_t>(const_cast<uint8_t*>(aData), aLength),
|
||||||
aIndex);
|
aIndex);
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
#include "mozilla/webrender/RenderThread.h"
|
#include "mozilla/webrender/RenderThread.h"
|
||||||
#include "mozilla/widget/CompositorWidget.h"
|
#include "mozilla/widget/CompositorWidget.h"
|
||||||
|
|
||||||
|
#ifdef XP_WIN
|
||||||
|
#include "dwrite.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using mozilla::Telemetry::LABELS_CONTENT_FRAME_TIME_REASON;
|
using mozilla::Telemetry::LABELS_CONTENT_FRAME_TIME_REASON;
|
||||||
|
|
||||||
#ifdef MOZ_GECKO_PROFILER
|
#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(
|
mozilla::ipc::IPCResult WebRenderBridgeParent::RecvUpdateResources(
|
||||||
nsTArray<OpUpdateResource>&& aResourceUpdates,
|
nsTArray<OpUpdateResource>&& aResourceUpdates,
|
||||||
nsTArray<RefCountedShmem>&& aSmallShmems,
|
nsTArray<RefCountedShmem>&& aSmallShmems,
|
||||||
|
@ -123,6 +123,9 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent,
|
|||||||
nsTArray<WebRenderParentCommand>&& commands) override;
|
nsTArray<WebRenderParentCommand>&& commands) override;
|
||||||
mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
|
mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
|
||||||
|
|
||||||
|
mozilla::ipc::IPCResult RecvValidateFontDescriptor(
|
||||||
|
nsTArray<uint8_t>&& aData) override;
|
||||||
|
|
||||||
mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
|
mozilla::ipc::IPCResult RecvSetLayersObserverEpoch(
|
||||||
const LayersObserverEpoch& aChildEpoch) override;
|
const LayersObserverEpoch& aChildEpoch) override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user