tor-browser

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

gloc.cc (3440B)


      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 #include "gloc.h"
      6 
      7 #include "name.h"
      8 
      9 namespace ots {
     10 
     11 bool OpenTypeGLOC::Parse(const uint8_t* data, size_t length) {
     12  Buffer table(data, length);
     13  OpenTypeNAME* name = static_cast<OpenTypeNAME*>(
     14      GetFont()->GetTypedTable(OTS_TAG_NAME));
     15  if (!name) {
     16    return DropGraphite("Required name table is missing");
     17  }
     18 
     19  if (!table.ReadU32(&this->version)) {
     20    return DropGraphite("Failed to read version");
     21  }
     22  if (this->version >> 16 != 1) {
     23    return DropGraphite("Unsupported table version: %u", this->version >> 16);
     24  }
     25  if (!table.ReadU16(&this->flags) || this->flags > 0b11) {
     26    return DropGraphite("Failed to read valid flags");
     27  }
     28  if (!table.ReadU16(&this->numAttribs)) {
     29    return DropGraphite("Failed to read numAttribs");
     30  }
     31 
     32  if (this->flags & ATTRIB_IDS && this->numAttribs * sizeof(uint16_t) >
     33                                  table.remaining()) {
     34    return DropGraphite("Failed to calculate length of locations");
     35  }
     36  size_t locations_len = (table.remaining() -
     37    (this->flags & ATTRIB_IDS ? this->numAttribs * sizeof(uint16_t) : 0)) /
     38    (this->flags & LONG_FORMAT ? sizeof(uint32_t) : sizeof(uint16_t));
     39  //this->locations.resize(locations_len);
     40  if (this->flags & LONG_FORMAT) {
     41    unsigned long last_location = 0;
     42    for (size_t i = 0; i < locations_len; ++i) {
     43      this->locations.emplace_back();
     44      uint32_t& location = this->locations[i];
     45      if (!table.ReadU32(&location) || location < last_location) {
     46        return DropGraphite("Failed to read valid locations[%lu]", i);
     47      }
     48      last_location = location;
     49    }
     50  } else {  // short (16-bit) offsets
     51    unsigned last_location = 0;
     52    for (size_t i = 0; i < locations_len; ++i) {
     53      uint16_t location;
     54      if (!table.ReadU16(&location) || location < last_location) {
     55        return DropGraphite("Failed to read valid locations[%lu]", i);
     56      }
     57      last_location = location;
     58      this->locations.push_back(static_cast<uint32_t>(location));
     59    }
     60  }
     61  if (this->locations.empty()) {
     62    return DropGraphite("No locations");
     63  }
     64 
     65  if (this->flags & ATTRIB_IDS) {  // attribIds array present
     66    //this->attribIds.resize(numAttribs);
     67    for (unsigned i = 0; i < this->numAttribs; ++i) {
     68      this->attribIds.emplace_back();
     69      if (!table.ReadU16(&this->attribIds[i]) ||
     70          !name->IsValidNameId(this->attribIds[i])) {
     71        return DropGraphite("Failed to read valid attribIds[%u]", i);
     72      }
     73    }
     74  }
     75 
     76  if (table.remaining()) {
     77    return Warning("%zu bytes unparsed", table.remaining());
     78  }
     79  return true;
     80 }
     81 
     82 bool OpenTypeGLOC::Serialize(OTSStream* out) {
     83  if (!out->WriteU32(this->version) ||
     84      !out->WriteU16(this->flags) ||
     85      !out->WriteU16(this->numAttribs) ||
     86      (this->flags & LONG_FORMAT ? !SerializeParts(this->locations, out) :
     87       ![&] {
     88         for (uint32_t location : this->locations) {
     89           if (!out->WriteU16(static_cast<uint16_t>(location))) {
     90             return false;
     91           }
     92         }
     93         return true;
     94       }()) ||
     95      (this->flags & ATTRIB_IDS && !SerializeParts(this->attribIds, out))) {
     96    return Error("Failed to write table");
     97  }
     98  return true;
     99 }
    100 
    101 const std::vector<uint32_t>& OpenTypeGLOC::GetLocations() {
    102  return this->locations;
    103 }
    104 
    105 }  // namespace ots