Coverage Report

Created: 2025-10-13 06:39

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