diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /gfx/ots/include | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/ots/include')
-rw-r--r-- | gfx/ots/include/opentype-sanitiser.h | 228 | ||||
-rw-r--r-- | gfx/ots/include/ots-memory-stream.h | 109 |
2 files changed, 337 insertions, 0 deletions
diff --git a/gfx/ots/include/opentype-sanitiser.h b/gfx/ots/include/opentype-sanitiser.h new file mode 100644 index 0000000000..2625783a53 --- /dev/null +++ b/gfx/ots/include/opentype-sanitiser.h @@ -0,0 +1,228 @@ +// Copyright (c) 2009-2017 The OTS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OPENTYPE_SANITISER_H_ +#define OPENTYPE_SANITISER_H_ + +#if defined(_WIN32) || defined(__CYGWIN__) + #define OTS_DLL_IMPORT __declspec(dllimport) + #define OTS_DLL_EXPORT __declspec(dllexport) +#else + #if __GNUC__ >= 4 + #define OTS_DLL_IMPORT __attribute__((visibility ("default"))) + #define OTS_DLL_EXPORT __attribute__((visibility ("default"))) + #endif +#endif + +#ifdef OTS_DLL + #ifdef OTS_DLL_EXPORTS + #define OTS_API OTS_DLL_EXPORT + #else + #define OTS_API OTS_DLL_IMPORT + #endif +#else + #define OTS_API +#endif + +#if defined(_WIN32) +#include <stdlib.h> +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef short int16_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned int uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#define ots_ntohl(x) _byteswap_ulong (x) +#define ots_ntohs(x) _byteswap_ushort (x) +#define ots_htonl(x) _byteswap_ulong (x) +#define ots_htons(x) _byteswap_ushort (x) +#else +#include <arpa/inet.h> +#include <stdint.h> +#define ots_ntohl(x) ntohl (x) +#define ots_ntohs(x) ntohs (x) +#define ots_htonl(x) htonl (x) +#define ots_htons(x) htons (x) +#endif + +#include <sys/types.h> + +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstring> + +#define OTS_TAG(c1,c2,c3,c4) ((uint32_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4)))) +#define OTS_UNTAG(tag) ((char)((tag)>>24)), ((char)((tag)>>16)), ((char)((tag)>>8)), ((char)(tag)) + +#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) +#define OTS_UNUSED __attribute__((unused)) +#elif defined(_MSC_VER) +#define OTS_UNUSED __pragma(warning(suppress: 4100 4101)) +#else +#define OTS_UNUSED +#endif + +namespace ots { + +// ----------------------------------------------------------------------------- +// This is an interface for an abstract stream class which is used for writing +// the serialised results out. +// ----------------------------------------------------------------------------- +class OTSStream { + public: + OTSStream() : chksum_(0) {} + + virtual ~OTSStream() {} + + virtual size_t size() = 0; + + // This should be implemented to perform the actual write. + virtual bool WriteRaw(const void *data, size_t length) = 0; + + bool Write(const void *data, size_t length) { + if (!length) return false; + + const size_t orig_length = length; + size_t offset = 0; + + size_t chksum_offset = Tell() & 3; + if (chksum_offset) { + const size_t l = std::min(length, static_cast<size_t>(4) - chksum_offset); + uint32_t tmp = 0; + std::memcpy(reinterpret_cast<uint8_t *>(&tmp) + chksum_offset, data, l); + chksum_ += ots_ntohl(tmp); + length -= l; + offset += l; + } + + while (length >= 4) { + uint32_t tmp; + std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset, + sizeof(uint32_t)); + chksum_ += ots_ntohl(tmp); + length -= 4; + offset += 4; + } + + if (length) { + if (length > 4) return false; // not reached + uint32_t tmp = 0; + std::memcpy(&tmp, + reinterpret_cast<const uint8_t*>(data) + offset, length); + chksum_ += ots_ntohl(tmp); + } + + return WriteRaw(data, orig_length); + } + + virtual bool Seek(off_t position) = 0; + virtual off_t Tell() const = 0; + + virtual bool Pad(size_t bytes) { + static const uint32_t kZero = 0; + while (bytes >= 4) { + if (!Write(&kZero, 4)) return false; + bytes -= 4; + } + while (bytes) { + static const uint8_t kZerob = 0; + if (!Write(&kZerob, 1)) return false; + bytes--; + } + return true; + } + + bool WriteU8(uint8_t v) { + return Write(&v, sizeof(v)); + } + + bool WriteU16(uint16_t v) { + v = ots_htons(v); + return Write(&v, sizeof(v)); + } + + bool WriteS16(int16_t v) { + v = ots_htons(v); + return Write(&v, sizeof(v)); + } + + bool WriteU24(uint32_t v) { + v = ots_htonl(v); + return Write(reinterpret_cast<uint8_t*>(&v)+1, 3); + } + + bool WriteU32(uint32_t v) { + v = ots_htonl(v); + return Write(&v, sizeof(v)); + } + + bool WriteS32(int32_t v) { + v = ots_htonl(v); + return Write(&v, sizeof(v)); + } + + bool WriteR64(uint64_t v) { + return Write(&v, sizeof(v)); + } + + void ResetChecksum() { + assert((Tell() & 3) == 0); + chksum_ = 0; + } + + uint32_t chksum() const { + return chksum_; + } + + protected: + uint32_t chksum_; +}; + +#ifdef __GCC__ +#define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3))) +#else +#define MSGFUNC_FMT_ATTR +#endif + +enum TableAction { + TABLE_ACTION_DEFAULT, // Use OTS's default action for that table + TABLE_ACTION_SANITIZE, // Sanitize the table, potentially dropping it + TABLE_ACTION_PASSTHRU, // Serialize the table unchanged + TABLE_ACTION_DROP // Drop the table +}; + +class OTS_API OTSContext { + public: + OTSContext() {} + virtual ~OTSContext() {} + + // Process a given OpenType file and write out a sanitized version + // output: a pointer to an object implementing the OTSStream interface. The + // sanitisied output will be written to this. In the even of a failure, + // partial output may have been written. + // input: the OpenType file + // length: the size, in bytes, of |input| + // index: if the input is a font collection and index is specified, then + // the corresponding font will be returned, otherwise the whole + // collection. Ignored for non-collection fonts. + bool Process(OTSStream *output, const uint8_t *input, size_t length, uint32_t index = -1); + + // This function will be called when OTS is reporting an error. + // level: the severity of the generated message: + // 0: error messages in case OTS fails to sanitize the font. + // 1: warning messages about issue OTS fixed in the sanitized font. + virtual void Message(int level OTS_UNUSED, const char *format OTS_UNUSED, ...) MSGFUNC_FMT_ATTR {} + + // This function will be called when OTS needs to decide what to do for a + // font table. + // tag: table tag formed with OTS_TAG() macro + virtual TableAction GetTableAction(uint32_t tag OTS_UNUSED) { return ots::TABLE_ACTION_DEFAULT; } +}; + +} // namespace ots + +#endif // OPENTYPE_SANITISER_H_ diff --git a/gfx/ots/include/ots-memory-stream.h b/gfx/ots/include/ots-memory-stream.h new file mode 100644 index 0000000000..cb844709c2 --- /dev/null +++ b/gfx/ots/include/ots-memory-stream.h @@ -0,0 +1,109 @@ +// Copyright (c) 2009-2017 The OTS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OTS_MEMORY_STREAM_H_ +#define OTS_MEMORY_STREAM_H_ + +#include <cstring> +#include <limits> + +#include "opentype-sanitiser.h" + +namespace ots { + +class MemoryStream : public OTSStream { + public: + MemoryStream(void *ptr, size_t length) + : ptr_(ptr), length_(length), off_(0) { + } + + size_t size() override { return length_; } + + bool WriteRaw(const void *data, size_t length) override { + if ((off_ + length > length_) || + (length > std::numeric_limits<size_t>::max() - off_)) { + return false; + } + std::memcpy(static_cast<char*>(ptr_) + off_, data, length); + off_ += length; + return true; + } + + bool Seek(off_t position) override { + if (position < 0) return false; + if (static_cast<size_t>(position) > length_) return false; + off_ = position; + return true; + } + + off_t Tell() const override { + return off_; + } + + private: + void* const ptr_; + size_t length_; + off_t off_; +}; + +class ExpandingMemoryStream : public OTSStream { + public: + ExpandingMemoryStream(size_t initial, size_t limit) + : length_(initial), limit_(limit), off_(0) { + ptr_ = new uint8_t[length_]; + } + + ~ExpandingMemoryStream() { + delete[] static_cast<uint8_t*>(ptr_); + } + + void* get() const { + return ptr_; + } + + size_t size() override { return limit_; } + + bool WriteRaw(const void *data, size_t length) override { + if ((off_ + length > length_) || + (length > std::numeric_limits<size_t>::max() - off_)) { + if (length_ == limit_) + return false; + size_t new_length = (length_ + 1) * 2; + if (new_length < length_) + return false; + if (new_length > limit_) + new_length = limit_; + uint8_t* new_buf = new uint8_t[new_length]; + std::memcpy(new_buf, ptr_, length_); + length_ = new_length; + delete[] static_cast<uint8_t*>(ptr_); + ptr_ = new_buf; + return WriteRaw(data, length); + } + std::memcpy(static_cast<char*>(ptr_) + off_, data, length); + off_ += length; + return true; + } + + bool Seek(off_t position) override { + if (position < 0) return false; + if (static_cast<size_t>(position) > length_) return false; + off_ = position; + return true; + } + + off_t Tell() const override { + return off_; + } + + private: + void* ptr_; + size_t length_; + const size_t limit_; + off_t off_; +}; + +} // namespace ots + +#endif // OTS_MEMORY_STREAM_H_ |