LCOV - code coverage report
Current view: top level - gfx/ots/src - ots.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 73 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 22 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009 The Chromium 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 OTS_H_
       6             : #define OTS_H_
       7             : 
       8             : #include <stddef.h>
       9             : #include <cstdarg>
      10             : #include <cstddef>
      11             : #include <cstdio>
      12             : #include <cstdlib>
      13             : #include <cstring>
      14             : #include <limits>
      15             : #include <map>
      16             : 
      17             : #include "opentype-sanitiser.h"
      18             : 
      19             : // arraysize borrowed from base/basictypes.h
      20             : template <typename T, size_t N>
      21             : char (&ArraySizeHelper(T (&array)[N]))[N];
      22             : #define arraysize(array) (sizeof(ArraySizeHelper(array)))
      23             : 
      24             : namespace ots {
      25             : 
      26             : #if !defined(OTS_DEBUG)
      27             : #define OTS_FAILURE() false
      28             : #else
      29             : #define OTS_FAILURE() \
      30             :   (\
      31             :     std::fprintf(stderr, "ERROR at %s:%d (%s)\n", \
      32             :                  __FILE__, __LINE__, __FUNCTION__) \
      33             :     && false\
      34             :   )
      35             : #endif
      36             : 
      37             : // All OTS_FAILURE_* macros ultimately evaluate to 'false', just like the original
      38             : // message-less OTS_FAILURE(), so that the current parser will return 'false' as
      39             : // its result (indicating a failure).
      40             : 
      41             : #if !defined(OTS_DEBUG)
      42             : #define OTS_MESSAGE_(level,otf_,...) \
      43             :   (otf_)->context->Message(level,__VA_ARGS__)
      44             : #else
      45             : #define OTS_MESSAGE_(level,otf_,...) \
      46             :   OTS_FAILURE(), \
      47             :   (otf_)->context->Message(level,__VA_ARGS__)
      48             : #endif
      49             : 
      50             : // Generate a simple message
      51             : #define OTS_FAILURE_MSG_(otf_,...) \
      52             :   (OTS_MESSAGE_(0,otf_,__VA_ARGS__), false)
      53             : 
      54             : #define OTS_WARNING_MSG_(otf_,...) \
      55             :   OTS_MESSAGE_(1,otf_,__VA_ARGS__)
      56             : 
      57             : // Generate a message with an associated table tag
      58             : #define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \
      59             :   (OTS_MESSAGE_(0,otf_,"%c%c%c%c: %s", OTS_UNTAG(tag_), msg_), false)
      60             : 
      61             : // Convenience macros for use in files that only handle a single table tag,
      62             : // defined as TABLE_NAME at the top of the file; the 'file' variable is
      63             : // expected to be the current OpenTypeFile pointer.
      64             : #define OTS_FAILURE_MSG(...) OTS_FAILURE_MSG_(font->file, TABLE_NAME ": " __VA_ARGS__)
      65             : 
      66             : #define OTS_WARNING(...) OTS_WARNING_MSG_(font->file, TABLE_NAME ": " __VA_ARGS__)
      67             : 
      68             : // -----------------------------------------------------------------------------
      69             : // Buffer helper class
      70             : //
      71             : // This class perform some trival buffer operations while checking for
      72             : // out-of-bounds errors. As a family they return false if anything is amiss,
      73             : // updating the current offset otherwise.
      74             : // -----------------------------------------------------------------------------
      75             : class Buffer {
      76             :  public:
      77           0 :   Buffer(const uint8_t *buf, size_t len)
      78           0 :       : buffer_(buf),
      79             :         length_(len),
      80           0 :         offset_(0) { }
      81             : 
      82           0 :   bool Skip(size_t n_bytes) {
      83           0 :     return Read(NULL, n_bytes);
      84             :   }
      85             : 
      86           0 :   bool Read(uint8_t *buf, size_t n_bytes) {
      87           0 :     if (n_bytes > 1024 * 1024 * 1024) {
      88           0 :       return OTS_FAILURE();
      89             :     }
      90           0 :     if ((offset_ + n_bytes > length_) ||
      91           0 :         (offset_ > length_ - n_bytes)) {
      92           0 :       return OTS_FAILURE();
      93             :     }
      94           0 :     if (buf) {
      95           0 :       std::memcpy(buf, buffer_ + offset_, n_bytes);
      96             :     }
      97           0 :     offset_ += n_bytes;
      98           0 :     return true;
      99             :   }
     100             : 
     101           0 :   inline bool ReadU8(uint8_t *value) {
     102           0 :     if (offset_ + 1 > length_) {
     103           0 :       return OTS_FAILURE();
     104             :     }
     105           0 :     *value = buffer_[offset_];
     106           0 :     ++offset_;
     107           0 :     return true;
     108             :   }
     109             : 
     110           0 :   bool ReadU16(uint16_t *value) {
     111           0 :     if (offset_ + 2 > length_) {
     112           0 :       return OTS_FAILURE();
     113             :     }
     114           0 :     std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
     115           0 :     *value = ntohs(*value);
     116           0 :     offset_ += 2;
     117           0 :     return true;
     118             :   }
     119             : 
     120           0 :   bool ReadS16(int16_t *value) {
     121           0 :     return ReadU16(reinterpret_cast<uint16_t*>(value));
     122             :   }
     123             : 
     124           0 :   bool ReadU24(uint32_t *value) {
     125           0 :     if (offset_ + 3 > length_) {
     126           0 :       return OTS_FAILURE();
     127             :     }
     128           0 :     *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
     129           0 :         static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
     130           0 :         static_cast<uint32_t>(buffer_[offset_ + 2]);
     131           0 :     offset_ += 3;
     132           0 :     return true;
     133             :   }
     134             : 
     135           0 :   bool ReadU32(uint32_t *value) {
     136           0 :     if (offset_ + 4 > length_) {
     137           0 :       return OTS_FAILURE();
     138             :     }
     139           0 :     std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
     140           0 :     *value = ntohl(*value);
     141           0 :     offset_ += 4;
     142           0 :     return true;
     143             :   }
     144             : 
     145           0 :   bool ReadS32(int32_t *value) {
     146           0 :     return ReadU32(reinterpret_cast<uint32_t*>(value));
     147             :   }
     148             : 
     149           0 :   bool ReadR64(uint64_t *value) {
     150           0 :     if (offset_ + 8 > length_) {
     151           0 :       return OTS_FAILURE();
     152             :     }
     153           0 :     std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
     154           0 :     offset_ += 8;
     155           0 :     return true;
     156             :   }
     157             : 
     158           0 :   const uint8_t *buffer() const { return buffer_; }
     159           0 :   size_t offset() const { return offset_; }
     160           0 :   size_t length() const { return length_; }
     161           0 :   size_t remaining() const { return length_ - offset_; }
     162             : 
     163           0 :   void set_offset(size_t newoffset) { offset_ = newoffset; }
     164             : 
     165             :  private:
     166             :   const uint8_t * const buffer_;
     167             :   const size_t length_;
     168             :   size_t offset_;
     169             : };
     170             : 
     171             : // Round a value up to the nearest multiple of 4. Don't round the value in the
     172             : // case that rounding up overflows.
     173           0 : template<typename T> T Round4(T value) {
     174           0 :   if (std::numeric_limits<T>::max() - value < 3) {
     175           0 :     return value;
     176             :   }
     177           0 :   return (value + 3) & ~3;
     178             : }
     179             : 
     180             : template<typename T> T Round2(T value) {
     181             :   if (value == std::numeric_limits<T>::max()) {
     182             :     return value;
     183             :   }
     184             :   return (value + 1) & ~1;
     185             : }
     186             : 
     187             : bool IsValidVersionTag(uint32_t tag);
     188             : 
     189             : #define FOR_EACH_TABLE_TYPE \
     190             :   F(cff, CFF) \
     191             :   F(cmap, CMAP) \
     192             :   F(cvt, CVT) \
     193             :   F(fpgm, FPGM) \
     194             :   F(gasp, GASP) \
     195             :   F(gdef, GDEF) \
     196             :   F(glyf, GLYF) \
     197             :   F(gpos, GPOS) \
     198             :   F(gsub, GSUB) \
     199             :   F(hdmx, HDMX) \
     200             :   F(head, HEAD) \
     201             :   F(hhea, HHEA) \
     202             :   F(hmtx, HMTX) \
     203             :   F(kern, KERN) \
     204             :   F(loca, LOCA) \
     205             :   F(ltsh, LTSH) \
     206             :   F(math, MATH) \
     207             :   F(maxp, MAXP) \
     208             :   F(name, NAME) \
     209             :   F(os2, OS2) \
     210             :   F(post, POST) \
     211             :   F(prep, PREP) \
     212             :   F(vdmx, VDMX) \
     213             :   F(vorg, VORG) \
     214             :   F(vhea, VHEA) \
     215             :   F(vmtx, VMTX)
     216             : 
     217             : #define F(name, capname) struct OpenType##capname;
     218             : FOR_EACH_TABLE_TYPE
     219             : #undef F
     220             : 
     221             : struct Font;
     222             : struct OpenTypeFile;
     223             : 
     224             : #define F(name, capname) \
     225             : bool ots_##name##_parse(Font *f, const uint8_t *d, size_t l); \
     226             : bool ots_##name##_should_serialise(Font *f); \
     227             : bool ots_##name##_serialise(OTSStream *s, Font *f); \
     228             : void ots_##name##_reuse(Font *f, Font *o);\
     229             : void ots_##name##_free(Font *f);
     230             : FOR_EACH_TABLE_TYPE
     231             : #undef F
     232             : 
     233             : struct Font {
     234           0 :   explicit Font(const OpenTypeFile *f)
     235           0 :       : file(f),
     236             :         version(0),
     237             :         num_tables(0),
     238             :         search_range(0),
     239             :         entry_selector(0),
     240           0 :         range_shift(0) {
     241             : #define F(name, capname) \
     242             :     name = NULL; \
     243             :     name##_reused = false;
     244           0 :     FOR_EACH_TABLE_TYPE
     245             : #undef F
     246           0 :   }
     247             : 
     248           0 :   ~Font() {
     249             : #define F(name, capname) \
     250             :     if (!name##_reused) {\
     251             :       ots_##name##_free(this); \
     252             :     }
     253           0 :     FOR_EACH_TABLE_TYPE
     254             : #undef F
     255           0 :   }
     256             : 
     257             :   const OpenTypeFile *file;
     258             : 
     259             :   uint32_t version;
     260             :   uint16_t num_tables;
     261             :   uint16_t search_range;
     262             :   uint16_t entry_selector;
     263             :   uint16_t range_shift;
     264             : 
     265             : #define F(name, capname) \
     266             :   OpenType##capname *name; \
     267             :   bool name##_reused;
     268             : FOR_EACH_TABLE_TYPE
     269             : #undef F
     270             : };
     271             : 
     272             : struct OutputTable {
     273             :   uint32_t tag;
     274             :   size_t offset;
     275             :   size_t length;
     276             :   uint32_t chksum;
     277             : 
     278           0 :   bool operator<(const OutputTable& other) const {
     279           0 :     return tag < other.tag;
     280             :   }
     281             : };
     282             : 
     283             : typedef std::map<uint32_t, std::pair<Font*, OutputTable> > TableMap;
     284             : 
     285           0 : struct OpenTypeFile {
     286             :   OTSContext *context;
     287             :   TableMap tables;
     288             : };
     289             : 
     290             : }  // namespace ots
     291             : 
     292             : #undef FOR_EACH_TABLE_TYPE
     293             : 
     294             : #endif  // OTS_H_

Generated by: LCOV version 1.13