tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

opentype-sanitiser.h (6502B)


      1 // Copyright (c) 2009-2017 The OTS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef OPENTYPE_SANITISER_H_
      6 #define OPENTYPE_SANITISER_H_
      7 
      8 #if defined(_WIN32) || defined(__CYGWIN__)
      9  #define OTS_DLL_IMPORT __declspec(dllimport)
     10  #define OTS_DLL_EXPORT __declspec(dllexport)
     11 #else
     12  #if __GNUC__ >= 4
     13    #define OTS_DLL_IMPORT __attribute__((visibility ("default")))
     14    #define OTS_DLL_EXPORT __attribute__((visibility ("default")))
     15  #endif
     16 #endif
     17 
     18 #ifdef OTS_DLL
     19  #ifdef OTS_DLL_EXPORTS
     20    #define OTS_API OTS_DLL_EXPORT
     21  #else
     22    #define OTS_API OTS_DLL_IMPORT
     23  #endif
     24 #else
     25  #define OTS_API
     26 #endif
     27 
     28 #if defined(_WIN32)
     29 #include <stdlib.h>
     30 typedef signed char int8_t;
     31 typedef unsigned char uint8_t;
     32 typedef short int16_t;
     33 typedef unsigned short uint16_t;
     34 typedef int int32_t;
     35 typedef unsigned int uint32_t;
     36 typedef __int64 int64_t;
     37 typedef unsigned __int64 uint64_t;
     38 #define ots_ntohl(x) _byteswap_ulong (x)
     39 #define ots_ntohs(x) _byteswap_ushort (x)
     40 #define ots_htonl(x) _byteswap_ulong (x)
     41 #define ots_htons(x) _byteswap_ushort (x)
     42 #else
     43 #include <arpa/inet.h>
     44 #include <stdint.h>
     45 #define ots_ntohl(x) ntohl (x)
     46 #define ots_ntohs(x) ntohs (x)
     47 #define ots_htonl(x) htonl (x)
     48 #define ots_htons(x) htons (x)
     49 #endif
     50 
     51 #include <sys/types.h>
     52 
     53 #include <algorithm>
     54 #include <cassert>
     55 #include <cstddef>
     56 #include <cstring>
     57 
     58 #define OTS_TAG(c1,c2,c3,c4) ((uint32_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
     59 #define OTS_UNTAG(tag)       ((char)((tag)>>24)), ((char)((tag)>>16)), ((char)((tag)>>8)), ((char)(tag))
     60 
     61 #if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
     62 #define OTS_UNUSED __attribute__((unused))
     63 #elif defined(_MSC_VER)
     64 #define OTS_UNUSED __pragma(warning(suppress: 4100 4101))
     65 #else
     66 #define OTS_UNUSED
     67 #endif
     68 
     69 namespace ots {
     70 
     71 // -----------------------------------------------------------------------------
     72 // This is an interface for an abstract stream class which is used for writing
     73 // the serialised results out.
     74 // -----------------------------------------------------------------------------
     75 class OTSStream {
     76 public:
     77  OTSStream() : chksum_(0) {}
     78 
     79  virtual ~OTSStream() {}
     80 
     81  virtual size_t size() = 0;
     82 
     83  // This should be implemented to perform the actual write.
     84  virtual bool WriteRaw(const void *data, size_t length) = 0;
     85 
     86  bool Write(const void *data, size_t length) {
     87    if (!length) return false;
     88 
     89    const size_t orig_length = length;
     90    size_t offset = 0;
     91 
     92    size_t chksum_offset = Tell() & 3;
     93    if (chksum_offset) {
     94      const size_t l = std::min(length, static_cast<size_t>(4) - chksum_offset);
     95      uint32_t tmp = 0;
     96      std::memcpy(reinterpret_cast<uint8_t *>(&tmp) + chksum_offset, data, l);
     97      chksum_ += ots_ntohl(tmp);
     98      length -= l;
     99      offset += l;
    100    }
    101 
    102    while (length >= 4) {
    103      uint32_t tmp;
    104      std::memcpy(&tmp, reinterpret_cast<const uint8_t *>(data) + offset,
    105        sizeof(uint32_t));
    106      chksum_ += ots_ntohl(tmp);
    107      length -= 4;
    108      offset += 4;
    109    }
    110 
    111    if (length) {
    112      if (length > 4) return false;  // not reached
    113      uint32_t tmp = 0;
    114      std::memcpy(&tmp,
    115                  reinterpret_cast<const uint8_t*>(data) + offset, length);
    116      chksum_ += ots_ntohl(tmp);
    117    }
    118 
    119    return WriteRaw(data, orig_length);
    120  }
    121 
    122  virtual bool Seek(off_t position) = 0;
    123  virtual off_t Tell() const = 0;
    124 
    125  virtual bool Pad(size_t bytes) {
    126    static const uint32_t kZero = 0;
    127    while (bytes >= 4) {
    128      if (!Write(&kZero, 4)) return false;
    129      bytes -= 4;
    130    }
    131    while (bytes) {
    132      static const uint8_t kZerob = 0;
    133      if (!Write(&kZerob, 1)) return false;
    134      bytes--;
    135    }
    136    return true;
    137  }
    138 
    139  bool WriteU8(uint8_t v) {
    140    return Write(&v, sizeof(v));
    141  }
    142 
    143  bool WriteU16(uint16_t v) {
    144    v = ots_htons(v);
    145    return Write(&v, sizeof(v));
    146  }
    147 
    148  bool WriteS16(int16_t v) {
    149    v = ots_htons(v);
    150    return Write(&v, sizeof(v));
    151  }
    152 
    153  bool WriteU24(uint32_t v) {
    154    v = ots_htonl(v);
    155    return Write(reinterpret_cast<uint8_t*>(&v)+1, 3);
    156  }
    157 
    158  bool WriteU32(uint32_t v) {
    159    v = ots_htonl(v);
    160    return Write(&v, sizeof(v));
    161  }
    162 
    163  bool WriteS32(int32_t v) {
    164    v = ots_htonl(v);
    165    return Write(&v, sizeof(v));
    166  }
    167 
    168  bool WriteR64(uint64_t v) {
    169    return Write(&v, sizeof(v));
    170  }
    171 
    172  void ResetChecksum() {
    173    assert((Tell() & 3) == 0);
    174    chksum_ = 0;
    175  }
    176 
    177  uint32_t chksum() const {
    178    return chksum_;
    179  }
    180 
    181 protected:
    182  uint32_t chksum_;
    183 };
    184 
    185 #ifdef __GCC__
    186 #define MSGFUNC_FMT_ATTR __attribute__((format(printf, 2, 3)))
    187 #else
    188 #define MSGFUNC_FMT_ATTR
    189 #endif
    190 
    191 enum TableAction {
    192  TABLE_ACTION_DEFAULT,  // Use OTS's default action for that table
    193  TABLE_ACTION_SANITIZE, // Sanitize the table, potentially dropping it
    194  TABLE_ACTION_PASSTHRU, // Serialize the table unchanged
    195  TABLE_ACTION_DROP,     // Drop the table
    196  TABLE_ACTION_SANITIZE_SOFT, // Sanitize the table, but without failing overall
    197                              // sanitzation even if this table fails/is dropped
    198 };
    199 
    200 class OTS_API OTSContext {
    201  public:
    202    OTSContext() {}
    203    virtual ~OTSContext() {}
    204 
    205    // Process a given OpenType file and write out a sanitized version
    206    //   output: a pointer to an object implementing the OTSStream interface. The
    207    //     sanitisied output will be written to this. In the even of a failure,
    208    //     partial output may have been written.
    209    //   input: the OpenType file
    210    //   length: the size, in bytes, of |input|
    211    //   index: if the input is a font collection and index is specified, then
    212    //     the corresponding font will be returned, otherwise the whole
    213    //     collection. Ignored for non-collection fonts.
    214    bool Process(OTSStream *output, const uint8_t *input, size_t length, uint32_t index = -1);
    215 
    216    // This function will be called when OTS is reporting an error.
    217    //   level: the severity of the generated message:
    218    //     0: error messages in case OTS fails to sanitize the font.
    219    //     1: warning messages about issue OTS fixed in the sanitized font.
    220    virtual void Message(int level OTS_UNUSED, const char *format OTS_UNUSED, ...) MSGFUNC_FMT_ATTR {}
    221 
    222    // This function will be called when OTS needs to decide what to do for a
    223    // font table.
    224    //   tag: table tag formed with OTS_TAG() macro
    225    virtual TableAction GetTableAction(uint32_t tag OTS_UNUSED) { return ots::TABLE_ACTION_DEFAULT; }
    226 };
    227 
    228 }  // namespace ots
    229 
    230 #endif  // OPENTYPE_SANITISER_H_