Coverage Report

Created: 2026-10-13 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/xpdf/TextString.cc
Line
Count
Source
1
//========================================================================
2
//
3
// TextString.cc
4
//
5
// Copyright 2011-2013 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <string.h>
12
#include "gmem.h"
13
#include "gmempp.h"
14
#include "GString.h"
15
#include "PDFDocEncoding.h"
16
#include "UTF8.h"
17
#include "TextString.h"
18
19
//------------------------------------------------------------------------
20
21
484k
TextString::TextString() {
22
484k
  u = NULL;
23
484k
  len = size = 0;
24
484k
}
25
26
65.8k
TextString::TextString(GString *s) {
27
65.8k
  u = NULL;
28
65.8k
  len = size = 0;
29
65.8k
  append(s);
30
65.8k
}
31
32
32.5k
TextString::TextString(TextString *s) {
33
32.5k
  len = size = s->len;
34
32.5k
  if (len) {
35
24.4k
    u = (Unicode *)gmallocn(size, sizeof(Unicode));
36
24.4k
    memcpy(u, s->u, len * sizeof(Unicode));
37
24.4k
  } else {
38
8.15k
    u = NULL;
39
8.15k
  }
40
32.5k
}
41
42
582k
TextString::~TextString() {
43
582k
  gfree(u);
44
582k
}
45
46
0
TextString *TextString::append(Unicode c) {
47
0
  expand(1);
48
0
  u[len] = c;
49
0
  ++len;
50
0
  return this;
51
0
}
52
53
65.8k
TextString *TextString::append(GString *s) {
54
65.8k
  return insert(len, s);
55
65.8k
}
56
57
32.9k
TextString *TextString::insert(int idx, Unicode c) {
58
32.9k
  if (idx >= 0 && idx <= len) {
59
32.9k
    expand(1);
60
32.9k
    if (idx < len) {
61
32.9k
      memmove(u + idx + 1, u + idx, (len - idx) * sizeof(Unicode));
62
32.9k
    }
63
32.9k
    u[idx] = c;
64
32.9k
    ++len;
65
32.9k
  }
66
32.9k
  return this;
67
32.9k
}
68
69
365k
TextString *TextString::insert(int idx, Unicode *u2, int n) {
70
365k
  if (idx >= 0 && idx <= len) {
71
365k
    expand(n);
72
365k
    if (idx < len) {
73
133k
      memmove(u + idx + n, u + idx, (len - idx) * sizeof(Unicode));
74
133k
    }
75
365k
    memcpy(u + idx, u2, n * sizeof(Unicode));
76
365k
    len += n;
77
365k
  }
78
365k
  return this;
79
365k
}
80
81
99.8k
TextString *TextString::insert(int idx, GString *s) {
82
99.8k
  Unicode uBuf[100];
83
99.8k
  int n, i;
84
85
99.8k
  if (idx >= 0 && idx <= len) {
86
    // look for a UTF-16BE BOM
87
99.8k
    if ((s->getChar(0) & 0xff) == 0xfe &&
88
31.1k
  (s->getChar(1) & 0xff) == 0xff) {
89
30.0k
      i = 2;
90
30.0k
      n = 0;
91
2.57M
      while (getUTF16BE(s, &i, uBuf + n)) {
92
2.54M
  ++n;
93
2.54M
  if (n == sizeof(uBuf) / sizeof(Unicode)) {
94
19.3k
    insert(idx, uBuf, n);
95
19.3k
    idx += n;
96
19.3k
    n = 0;
97
19.3k
  }
98
2.54M
      }
99
30.0k
      if (n > 0) {
100
29.5k
  insert(idx, uBuf, n);
101
29.5k
      }
102
103
    // look for a UTF-16LE BOM
104
    // (technically, this isn't allowed by the PDF spec, but some
105
    // PDF files use it)
106
69.7k
    } else if ((s->getChar(0) & 0xff) == 0xff &&
107
7.13k
         (s->getChar(1) & 0xff) == 0xfe) {
108
6.85k
      i = 2;
109
6.85k
      n = 0;
110
18.8M
      while (getUTF16LE(s, &i, uBuf + n)) {
111
18.8M
  ++n;
112
18.8M
  if (n == sizeof(uBuf) / sizeof(Unicode)) {
113
187k
    insert(idx, uBuf, n);
114
187k
    idx += n;
115
187k
    n = 0;
116
187k
  }
117
18.8M
      }
118
6.85k
      if (n > 0) {
119
5.15k
  insert(idx, uBuf, n);
120
5.15k
      }
121
122
    // look for a UTF-8 BOM
123
62.8k
    } else if ((s->getChar(0) & 0xff) == 0xef &&
124
1.52k
         (s->getChar(1) & 0xff) == 0xbb &&
125
1.30k
         (s->getChar(2) & 0xff) == 0xbf) {
126
1.03k
      i = 3;
127
1.03k
      n = 0;
128
12.4M
      while (getUTF8(s, &i, uBuf + n)) {
129
12.4M
  ++n;
130
12.4M
  if (n == sizeof(uBuf) / sizeof(Unicode)) {
131
123k
    insert(idx, uBuf, n);
132
123k
    idx += n;
133
123k
    n = 0;
134
123k
  }
135
12.4M
      }
136
1.03k
      if (n > 0) {
137
741
  insert(idx, uBuf, n);
138
741
      }
139
140
    // otherwise, use PDFDocEncoding
141
61.8k
    } else {
142
61.8k
      n = s->getLength();
143
61.8k
      expand(n);
144
61.8k
      if (idx < len) {
145
6.64k
  memmove(u + idx + n, u + idx, (len - idx) * sizeof(Unicode));
146
6.64k
      }
147
17.0M
      for (i = 0; i < n; ++i) {
148
16.9M
  u[idx + i] = pdfDocEncoding[s->getChar(i) & 0xff];
149
16.9M
      }
150
61.8k
      len += n;
151
61.8k
    }
152
99.8k
  }
153
99.8k
  return this;
154
99.8k
}
155
156
460k
void TextString::expand(int delta) {
157
460k
  int newLen;
158
159
460k
  newLen = len + delta;
160
460k
  if (delta > INT_MAX - len) {
161
    // trigger an out-of-memory error
162
0
    size = -1;
163
460k
  } else if (newLen <= size) {
164
368k
    return;
165
368k
  } else if (size > 0 && size <= INT_MAX / 2 && size*2 >= newLen) {
166
28.0k
    size *= 2;
167
63.6k
  } else {
168
63.6k
    size = newLen;
169
63.6k
  }
170
91.6k
  u = (Unicode *)greallocn(u, size, sizeof(Unicode));
171
91.6k
}
172
173
0
GString *TextString::toPDFTextString() {
174
0
  GString *s;
175
0
  GBool useUnicode;
176
0
  int i;
177
178
0
  useUnicode = gFalse;
179
0
  for (i = 0; i < len; ++i) {
180
0
    if (u[i] >= 0x80) {
181
0
      useUnicode = gTrue;
182
0
      break;
183
0
    }
184
0
  }
185
0
  s = new GString();
186
0
  if (useUnicode) {
187
0
    s->append((char)0xfe);
188
0
    s->append((char)0xff);
189
0
    for (i = 0; i < len; ++i) {
190
0
      s->append((char)(u[i] >> 8));
191
0
      s->append((char)u[i]);
192
0
    }
193
0
  } else {
194
0
    for (i = 0; i < len; ++i) {
195
0
      s->append((char)u[i]);
196
0
    }
197
0
  }
198
0
  return s;
199
0
}
200
201
1.16k
GString *TextString::toUTF8() {
202
1.16k
  GString *s = new GString();
203
82.5k
  for (int i = 0; i < len; ++i) {
204
81.3k
    char buf[8];
205
81.3k
    int n = mapUTF8(u[i], buf, sizeof(buf));
206
81.3k
    s->append(buf, n);
207
81.3k
  }
208
1.16k
  return s;
209
1.16k
}