Coverage Report

Created: 2025-11-11 07:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.05/xpdf/UnicodeRemapping.cc
Line
Count
Source
1
//========================================================================
2
//
3
// UnicodeRemapping.cc
4
//
5
// Copyright 2018 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <stdio.h>
12
#include <string.h>
13
#include "gmem.h"
14
#include "gmempp.h"
15
#include "gfile.h"
16
#include "GString.h"
17
#include "Error.h"
18
#include "UnicodeRemapping.h"
19
20
//------------------------------------------------------------------------
21
22
0
#define maxUnicodeString 8
23
24
struct UnicodeRemappingString {
25
  Unicode in;
26
  Unicode out[maxUnicodeString];
27
  int len;
28
};
29
30
//------------------------------------------------------------------------
31
32
static int hexCharVals[256] = {
33
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x
34
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 1x
35
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 2x
36
   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, // 3x
37
  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 4x
38
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 5x
39
  -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 6x
40
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 7x
41
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 8x
42
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 9x
43
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ax
44
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Bx
45
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Cx
46
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Dx
47
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ex
48
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  // Fx
49
};
50
51
// Parse a <len>-byte hex string <s> into *<val>.  Returns false on
52
// error.
53
0
static GBool parseHex(char *s, int len, Guint *val) {
54
0
  int i, x;
55
56
0
  *val = 0;
57
0
  for (i = 0; i < len; ++i) {
58
0
    x = hexCharVals[s[i] & 0xff];
59
0
    if (x < 0) {
60
0
      return gFalse;
61
0
    }
62
0
    *val = (*val << 4) + x;
63
0
  }
64
0
  return gTrue;
65
0
}
66
67
//------------------------------------------------------------------------
68
69
146
UnicodeRemapping::UnicodeRemapping() {
70
37.5k
  for (int i = 0; i < 256; ++i) {
71
37.3k
    page0[i] = (Unicode)i;
72
37.3k
  }
73
146
  sMap = NULL;
74
146
  sMapLen = sMapSize = 0;
75
146
}
76
77
146
UnicodeRemapping::~UnicodeRemapping() {
78
146
  gfree(sMap);
79
146
}
80
81
0
void UnicodeRemapping::addRemapping(Unicode in, Unicode *out, int len) {
82
0
  int i, j;
83
84
0
  if (in < 256 && len == 1) {
85
0
    page0[in] = out[0];
86
0
  } else {
87
0
    if (in < 256) {
88
0
      page0[in] = 0xffffffff;
89
0
    }
90
0
    if (sMapLen == sMapSize) {
91
0
      sMapSize += 16;
92
0
      sMap = (UnicodeRemappingString *)
93
0
           greallocn(sMap, sMapSize, sizeof(UnicodeRemappingString));
94
0
    }
95
0
    i = findSMap(in);
96
0
    if (i < sMapLen) {
97
0
      memmove(sMap + i + 1, sMap + i,
98
0
        (sMapLen - i) * sizeof(UnicodeRemappingString));
99
0
    }
100
0
    sMap[i].in = in;
101
0
    for (j = 0; j < len && j < maxUnicodeString; ++j) {
102
0
      sMap[i].out[j] = out[j];
103
0
    }
104
0
    sMap[i].len = j;
105
0
    ++sMapLen;
106
0
  }
107
0
}
108
109
0
void UnicodeRemapping::parseFile(GString *fileName) {
110
0
  FILE *f;
111
0
  char buf[256];
112
0
  Unicode in;
113
0
  Unicode out[maxUnicodeString];
114
0
  char *tok;
115
0
  int line, n;
116
117
0
  if (!(f = openFile(fileName->getCString(), "r"))) {
118
0
    error(errSyntaxError, -1, "Couldn't open unicodeRemapping file '{0:t}'",
119
0
    fileName);
120
0
    return;
121
0
  }
122
123
0
  line = 0;
124
0
  while (getLine(buf, sizeof(buf), f)) {
125
0
    ++line;
126
0
    if (!(tok = strtok(buf, " \t\r\n")) ||
127
0
  !parseHex(tok, (int)strlen(tok), &in)) {
128
0
      error(errSyntaxWarning, -1,
129
0
      "Bad line ({0:d}) in unicodeRemapping file '{1:t}'",
130
0
      line, fileName);
131
0
      continue;
132
0
    }
133
0
    n = 0;
134
0
    while (n < maxUnicodeString) {
135
0
      if (!(tok = strtok(NULL, " \t\r\n"))) {
136
0
  break;
137
0
      }
138
0
      if (!parseHex(tok, (int)strlen(tok), &out[n])) {
139
0
  error(errSyntaxWarning, -1,
140
0
        "Bad line ({0:d}) in unicodeRemapping file '{1:t}'",
141
0
        line, fileName);
142
0
  break;
143
0
      }
144
0
      ++n;
145
0
    }
146
0
    addRemapping(in, out, n);
147
0
  }
148
149
0
  fclose(f);
150
0
}
151
152
// Determine the location in sMap to insert/replace the entry for [u].
153
0
int UnicodeRemapping::findSMap(Unicode u) {
154
0
  int a, b, m;
155
156
0
  a = -1;
157
0
  b = sMapLen;
158
  // invariant: sMap[a].in < u <= sMap[b].in
159
0
  while (b - a > 1) {
160
0
    m = (a + b) / 2;
161
0
    if (sMap[m].in < u) {
162
0
      a = m;
163
0
    } else {
164
0
      b = m;
165
0
    }
166
0
  }
167
0
  return b;
168
0
}
169
170
0
int UnicodeRemapping::map(Unicode in, Unicode *out, int size) {
171
0
  int a, b, m, i;
172
173
0
  if (in < 256 && page0[in] != 0xffffffff) {
174
0
    out[0] = page0[in];
175
0
    return 1;
176
0
  }
177
178
0
  a = -1;
179
0
  b = sMapLen;
180
  // invariant: sMap[a].in < in < sMap[b].in
181
0
  while (b - a > 1) {
182
0
    m = (a + b) / 2;
183
0
    if (sMap[m].in < in) {
184
0
      a = m;
185
0
    } else if (in < sMap[m].in) {
186
0
      b = m;
187
0
    } else {
188
0
      for (i = 0; i < sMap[m].len && i < size; ++i) {
189
0
  out[i] = sMap[m].out[i];
190
0
      }
191
0
      return i;
192
0
    }
193
0
  }
194
195
0
  out[0] = in;
196
0
  return 1;
197
0
}