Commit 580063e0 authored by bbudge@chromium.org's avatar bbudge@chromium.org

Revert "Modify content::GetFontTable to allow clients to control what is read."

This reverts commit 54d2b618.
This caused a regression:
https://code.google.com/p/chromium/issues/detail?id=223716

TBR=brettw@chromium.org
BUG=223716

Review URL: https://codereview.chromium.org/13071008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190510 0039d316-1c4b-4281-b951-d872f2087c98
parent 2141fe97
...@@ -57,12 +57,11 @@ int32_t PepperFlashFontFileHost::OnGetFontTable( ...@@ -57,12 +57,11 @@ int32_t PepperFlashFontFileHost::OnGetFontTable(
#if defined(OS_LINUX) || defined(OS_OPENBSD) #if defined(OS_LINUX) || defined(OS_OPENBSD)
if (fd_ != -1) { if (fd_ != -1) {
size_t length = 0; size_t length = 0;
if (content::GetFontTable(fd_, table, 0 /* offset */, NULL, &length)) { if (content::GetFontTable(fd_, table, NULL, &length)) {
contents.resize(length); contents.resize(length);
uint8_t* contents_ptr = uint8_t* contents_ptr =
reinterpret_cast<uint8_t*>(const_cast<char*>(contents.c_str())); reinterpret_cast<uint8_t*>(const_cast<char*>(contents.c_str()));
if (content::GetFontTable(fd_, table, 0 /* offset */, if (content::GetFontTable(fd_, table, contents_ptr, &length)) {
contents_ptr, &length)) {
result = PP_OK; result = PP_OK;
} else { } else {
contents.clear(); contents.clear();
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/safe_numerics.h"
#include "base/utf_string_conversions.h" #include "base/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
...@@ -62,8 +61,8 @@ class PrivateFontFile : public ppapi::Resource { ...@@ -62,8 +61,8 @@ class PrivateFontFile : public ppapi::Resource {
uint32_t* output_length) { uint32_t* output_length) {
size_t temp_size = static_cast<size_t>(*output_length); size_t temp_size = static_cast<size_t>(*output_length);
bool rv = content::GetFontTable( bool rv = content::GetFontTable(
fd_, table, 0 /* offset */, static_cast<uint8_t*>(output), &temp_size); fd_, table, static_cast<uint8_t*>(output), &temp_size);
*output_length = base::checked_numeric_cast<uint32_t>(temp_size); *output_length = static_cast<uint32_t>(temp_size);
return rv; return rv;
} }
......
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include "base/pickle.h" #include "base/pickle.h"
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "base/posix/unix_domain_socket_linux.h" #include "base/posix/unix_domain_socket_linux.h"
#include "base/safe_numerics.h"
#include "base/sys_byteorder.h"
#include "content/common/sandbox_linux.h" #include "content/common/sandbox_linux.h"
#include "third_party/WebKit/Source/Platform/chromium/public/linux/WebFontFamily.h" #include "third_party/WebKit/Source/Platform/chromium/public/linux/WebFontFamily.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontRenderStyle.h" #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebFontRenderStyle.h"
...@@ -101,74 +99,79 @@ int MatchFontWithFallback(const std::string& face, bool bold, ...@@ -101,74 +99,79 @@ int MatchFontWithFallback(const std::string& face, bool bold,
return fd; return fd;
} }
bool GetFontTable(int fd, uint32_t table_tag, off_t offset, bool GetFontTable(int fd, uint32_t table, uint8_t* output,
uint8_t* output, size_t* output_length) { size_t* output_length) {
if (offset < 0) if (table == 0) {
return false;
size_t data_length = 0; // the length of the file data.
off_t data_offset = 0; // the offset of the data in the file.
if (table_tag == 0) {
// Get the entire font file.
struct stat st; struct stat st;
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return false; return false;
data_length = base::checked_numeric_cast<size_t>(st.st_size); size_t length = st.st_size;
} else { if (!output) {
// Get a font table. Read the header to find its offset in the file. *output_length = length;
uint16_t num_tables; return true;
ssize_t n = HANDLE_EINTR(pread(fd, &num_tables, sizeof(num_tables), }
4 /* skip the font type */)); if (*output_length < length)
if (n != sizeof(num_tables))
return false; return false;
// Font data is stored in net (big-endian) order. *output_length = length;
num_tables = base::NetToHost16(num_tables); ssize_t n = HANDLE_EINTR(pread(fd, output, length, 0));
if (n != static_cast<ssize_t>(length))
// Read the table directory.
static const size_t kTableEntrySize = 16;
const size_t directory_size = num_tables * kTableEntrySize;
scoped_array<uint8_t> table_entries(new uint8_t[directory_size]);
n = HANDLE_EINTR(pread(fd, table_entries.get(), directory_size,
12 /* skip the SFNT header */));
if (n != base::checked_numeric_cast<ssize_t>(directory_size))
return false; return false;
return true;
}
unsigned num_tables;
uint8_t num_tables_buf[2];
for (uint16_t i = 0; i < num_tables; ++i) { ssize_t n = HANDLE_EINTR(pread(fd, &num_tables_buf, sizeof(num_tables_buf),
uint8_t* entry = table_entries.get() + i * kTableEntrySize; 4 /* skip the font type */));
uint32_t tag = base::NetToHost32(*reinterpret_cast<uint32_t*>(entry)); if (n != sizeof(num_tables_buf))
if (tag == table_tag) { return false;
// Font data is stored in net (big-endian) order.
data_offset = num_tables = static_cast<unsigned>(num_tables_buf[0]) << 8 |
base::NetToHost32(*reinterpret_cast<uint32_t*>(entry + 8)); num_tables_buf[1];
data_length =
base::NetToHost32(*reinterpret_cast<uint32_t*>(entry + 12)); // The size in bytes of an entry in the table directory.
break; static const unsigned kTableEntrySize = 16;
} scoped_array<uint8_t> table_entries(
new uint8_t[num_tables * kTableEntrySize]);
n = HANDLE_EINTR(pread(fd, table_entries.get(), num_tables * kTableEntrySize,
12 /* skip the SFNT header */));
if (n != static_cast<ssize_t>(num_tables * kTableEntrySize))
return false;
size_t offset;
size_t length = 0;
for (unsigned i = 0; i < num_tables; i++) {
const uint8_t* entry = table_entries.get() + i * kTableEntrySize;
if (memcmp(entry, &table, sizeof(table)) == 0) {
offset = static_cast<size_t>(entry[8]) << 24 |
static_cast<size_t>(entry[9]) << 16 |
static_cast<size_t>(entry[10]) << 8 |
static_cast<size_t>(entry[11]);
length = static_cast<size_t>(entry[12]) << 24 |
static_cast<size_t>(entry[13]) << 16 |
static_cast<size_t>(entry[14]) << 8 |
static_cast<size_t>(entry[15]);
break;
} }
} }
if (!data_length) if (!length)
return false;
// Clamp |offset| inside the allowable range. This allows the read to succeed
// but return 0 bytes.
offset = std::min(offset, base::checked_numeric_cast<off_t>(data_length));
// Make sure it's safe to add the data offset and the caller's logical offset.
// Define the maximum positive offset on 32 bit systems.
static const off_t kMaxPositiveOffset32 = 0x7FFFFFFF; // 2 GB - 1.
if ((offset > kMaxPositiveOffset32 / 2) ||
(data_offset > kMaxPositiveOffset32 / 2))
return false; return false;
data_offset += offset;
data_length -= offset; if (!output) {
*output_length = length;
if (output) { return true;
// 'output_length' holds the maximum amount of data the caller can accept.
data_length = std::min(data_length, *output_length);
ssize_t n = HANDLE_EINTR(pread(fd, output, data_length, data_offset));
if (n != base::checked_numeric_cast<ssize_t>(data_length))
return false;
} }
*output_length = data_length;
if (*output_length < length)
return false;
*output_length = length;
n = HANDLE_EINTR(pread(fd, output, length, offset));
if (n != static_cast<ssize_t>(length))
return false;
return true; return true;
} }
......
...@@ -31,16 +31,14 @@ CONTENT_EXPORT int MatchFontWithFallback(const std::string& face, bool bold, ...@@ -31,16 +31,14 @@ CONTENT_EXPORT int MatchFontWithFallback(const std::string& face, bool bold,
// GetFontTable loads a specified font table from an open SFNT file. // GetFontTable loads a specified font table from an open SFNT file.
// fd: a file descriptor to the SFNT file. The position doesn't matter. // fd: a file descriptor to the SFNT file. The position doesn't matter.
// table_tag: the table tag in *big-endian* format, or 0 for the entire font. // table: the table in *big-endian* format, or 0 for the whole font file.
// offset: offset into the table or entire font where loading should start.
// The offset must be between 0 and 1 GB - 1.
// output: a buffer of size output_length that gets the data. can be 0, in // output: a buffer of size output_length that gets the data. can be 0, in
// which case output_length will be set to the required size in bytes. // which case output_length will be set to the required size in bytes.
// output_length: size of output, if it's not 0. // output_length: size of output, if it's not 0.
// //
// returns: true on success. // returns: true on success.
CONTENT_EXPORT bool GetFontTable(int fd, uint32_t table_tag, off_t offset, CONTENT_EXPORT bool GetFontTable(int fd, uint32_t table, uint8_t* output,
uint8_t* output, size_t* output_length); size_t* output_length);
}; // namespace content }; // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment