Commit 2699ecf13e8559b136ded1986bf18e1a0a51011f

Authored by Jay Berkenbilt
1 parent d9747486

Push QPDFTokenizer members into a nested structure

This is for protection against future ABI breaking changes.
include/qpdf/QPDFTokenizer.hh
... ... @@ -165,31 +165,53 @@ class QPDFTokenizer
165 165 size_t max_len = 0);
166 166  
167 167 private:
168   - void reset();
  168 + // Do not implement copy or assignment
  169 + QPDFTokenizer(QPDFTokenizer const&);
  170 + QPDFTokenizer& operator=(QPDFTokenizer const&);
  171 +
169 172 void resolveLiteral();
170 173 bool isSpace(char);
171 174  
172   - // Lexer state
173   - enum { st_top, st_in_space, st_in_comment, st_in_string, st_lt, st_gt,
174   - st_literal, st_in_hexstring, st_token_ready } state;
175   -
176   - bool pound_special_in_name;
177   - bool allow_eof;
178   - bool include_ignorable;
179   -
180   - // Current token accumulation
181   - token_type_e type;
182   - std::string val;
183   - std::string raw_val;
184   - std::string error_message;
185   - bool unread_char;
186   - char char_to_unread;
187   -
188   - // State for strings
189   - int string_depth;
190   - bool string_ignoring_newline;
191   - char bs_num_register[4];
192   - bool last_char_was_bs;
  175 + enum state_e {
  176 + st_top, st_in_space, st_in_comment, st_in_string, st_lt, st_gt,
  177 + st_literal, st_in_hexstring, st_token_ready
  178 + };
  179 +
  180 + class Members
  181 + {
  182 + friend class QPDFTokenizer;
  183 +
  184 + public:
  185 + QPDF_DLL
  186 + ~Members();
  187 +
  188 + private:
  189 + Members();
  190 + Members(Members const&);
  191 + void reset();
  192 +
  193 + // Lexer state
  194 + state_e state;
  195 +
  196 + bool pound_special_in_name;
  197 + bool allow_eof;
  198 + bool include_ignorable;
  199 +
  200 + // Current token accumulation
  201 + token_type_e type;
  202 + std::string val;
  203 + std::string raw_val;
  204 + std::string error_message;
  205 + bool unread_char;
  206 + char char_to_unread;
  207 +
  208 + // State for strings
  209 + int string_depth;
  210 + bool string_ignoring_newline;
  211 + char bs_num_register[4];
  212 + bool last_char_was_bs;
  213 + };
  214 + PointerHolder<Members> m;
193 215 };
194 216  
195 217 #endif // __QPDFTOKENIZER_HH__
... ...
libqpdf/QPDFTokenizer.cc
... ... @@ -12,7 +12,7 @@
12 12 #include <string.h>
13 13 #include <cstdlib>
14 14  
15   -QPDFTokenizer::QPDFTokenizer() :
  15 +QPDFTokenizer::Members::Members() :
16 16 pound_special_in_name(true),
17 17 allow_eof(false),
18 18 include_ignorable(false)
... ... @@ -21,22 +21,46 @@ QPDFTokenizer::QPDFTokenizer() :
21 21 }
22 22  
23 23 void
  24 +QPDFTokenizer::Members::reset()
  25 +{
  26 + state = st_top;
  27 + type = tt_bad;
  28 + val = "";
  29 + raw_val = "";
  30 + error_message = "";
  31 + unread_char = false;
  32 + char_to_unread = '\0';
  33 + string_depth = 0;
  34 + string_ignoring_newline = false;
  35 + last_char_was_bs = false;
  36 +}
  37 +
  38 +QPDFTokenizer::Members::~Members()
  39 +{
  40 +}
  41 +
  42 +QPDFTokenizer::QPDFTokenizer() :
  43 + m(new Members())
  44 +{
  45 +}
  46 +
  47 +void
24 48 QPDFTokenizer::allowPoundAnywhereInName()
25 49 {
26 50 QTC::TC("qpdf", "QPDFTokenizer allow pound anywhere in name");
27   - this->pound_special_in_name = false;
  51 + this->m->pound_special_in_name = false;
28 52 }
29 53  
30 54 void
31 55 QPDFTokenizer::allowEOF()
32 56 {
33   - this->allow_eof = true;
  57 + this->m->allow_eof = true;
34 58 }
35 59  
36 60 void
37 61 QPDFTokenizer::includeIgnorable()
38 62 {
39   - this->include_ignorable = true;
  63 + this->m->include_ignorable = true;
40 64 }
41 65  
42 66 bool
... ... @@ -46,34 +70,19 @@ QPDFTokenizer::isSpace(char ch)
46 70 }
47 71  
48 72 void
49   -QPDFTokenizer::reset()
50   -{
51   - state = st_top;
52   - type = tt_bad;
53   - val = "";
54   - raw_val = "";
55   - error_message = "";
56   - unread_char = false;
57   - char_to_unread = '\0';
58   - string_depth = 0;
59   - string_ignoring_newline = false;
60   - last_char_was_bs = false;
61   -}
62   -
63   -void
64 73 QPDFTokenizer::resolveLiteral()
65 74 {
66   - if ((val.length() > 0) && (val.at(0) == '/'))
  75 + if ((this->m->val.length() > 0) && (this->m->val.at(0) == '/'))
67 76 {
68   - type = tt_name;
  77 + this->m->type = tt_name;
69 78 // Deal with # in name token. Note: '/' by itself is a
70 79 // valid name, so don't strip leading /. That way we
71 80 // don't have to deal with the empty string as a name.
72 81 std::string nval = "/";
73   - char const* valstr = val.c_str() + 1;
  82 + char const* valstr = this->m->val.c_str() + 1;
74 83 for (char const* p = valstr; *p; ++p)
75 84 {
76   - if ((*p == '#') && this->pound_special_in_name)
  85 + if ((*p == '#') && this->m->pound_special_in_name)
77 86 {
78 87 if (p[1] && p[2] &&
79 88 QUtil::is_hex_digit(p[1]) && QUtil::is_hex_digit(p[2]))
... ... @@ -85,9 +94,9 @@ QPDFTokenizer::resolveLiteral()
85 94 char ch = static_cast<char>(strtol(num, 0, 16));
86 95 if (ch == '\0')
87 96 {
88   - type = tt_bad;
  97 + this->m->type = tt_bad;
89 98 QTC::TC("qpdf", "QPDF_Tokenizer null in name");
90   - error_message =
  99 + this->m->error_message =
91 100 "null character not allowed in name token";
92 101 nval += "#00";
93 102 }
... ... @@ -100,8 +109,8 @@ QPDFTokenizer::resolveLiteral()
100 109 else
101 110 {
102 111 QTC::TC("qpdf", "QPDF_Tokenizer bad name");
103   - type = tt_bad;
104   - error_message = "invalid name token";
  112 + this->m->type = tt_bad;
  113 + this->m->error_message = "invalid name token";
105 114 nval += *p;
106 115 }
107 116 }
... ... @@ -110,40 +119,40 @@ QPDFTokenizer::resolveLiteral()
110 119 nval += *p;
111 120 }
112 121 }
113   - val = nval;
  122 + this->m->val = nval;
114 123 }
115   - else if (QUtil::is_number(val.c_str()))
  124 + else if (QUtil::is_number(this->m->val.c_str()))
116 125 {
117   - if (val.find('.') != std::string::npos)
  126 + if (this->m->val.find('.') != std::string::npos)
118 127 {
119   - type = tt_real;
  128 + this->m->type = tt_real;
120 129 }
121 130 else
122 131 {
123   - type = tt_integer;
  132 + this->m->type = tt_integer;
124 133 }
125 134 }
126   - else if ((val == "true") || (val == "false"))
  135 + else if ((this->m->val == "true") || (this->m->val == "false"))
127 136 {
128   - type = tt_bool;
  137 + this->m->type = tt_bool;
129 138 }
130   - else if (val == "null")
  139 + else if (this->m->val == "null")
131 140 {
132   - type = tt_null;
  141 + this->m->type = tt_null;
133 142 }
134 143 else
135 144 {
136 145 // I don't really know what it is, so leave it as tt_word.
137 146 // Lots of cases ($, #, etc.) other than actual words fall
138 147 // into this category, but that's okay at least for now.
139   - type = tt_word;
  148 + this->m->type = tt_word;
140 149 }
141 150 }
142 151  
143 152 void
144 153 QPDFTokenizer::presentCharacter(char ch)
145 154 {
146   - if (state == st_token_ready)
  155 + if (this->m->state == st_token_ready)
147 156 {
148 157 throw std::logic_error(
149 158 "INTERNAL ERROR: QPDF tokenizer presented character "
... ... @@ -157,205 +166,210 @@ QPDFTokenizer::presentCharacter(char ch)
157 166 // the character that caused a state change in the new state.
158 167  
159 168 bool handled = true;
160   - if (state == st_top)
  169 + if (this->m->state == st_top)
161 170 {
162 171 // Note: we specifically do not use ctype here. It is
163 172 // locale-dependent.
164 173 if (isSpace(ch))
165 174 {
166   - if (this->include_ignorable)
  175 + if (this->m->include_ignorable)
167 176 {
168   - state = st_in_space;
169   - val += ch;
  177 + this->m->state = st_in_space;
  178 + this->m->val += ch;
170 179 }
171 180 }
172 181 else if (ch == '%')
173 182 {
174   - state = st_in_comment;
175   - if (this->include_ignorable)
  183 + this->m->state = st_in_comment;
  184 + if (this->m->include_ignorable)
176 185 {
177   - val += ch;
  186 + this->m->val += ch;
178 187 }
179 188 }
180 189 else if (ch == '(')
181 190 {
182   - string_depth = 1;
183   - string_ignoring_newline = false;
184   - memset(bs_num_register, '\0', sizeof(bs_num_register));
185   - last_char_was_bs = false;
186   - state = st_in_string;
  191 + this->m->string_depth = 1;
  192 + this->m->string_ignoring_newline = false;
  193 + memset(this->m->bs_num_register, '\0',
  194 + sizeof(this->m->bs_num_register));
  195 + this->m->last_char_was_bs = false;
  196 + this->m->state = st_in_string;
187 197 }
188 198 else if (ch == '<')
189 199 {
190   - state = st_lt;
  200 + this->m->state = st_lt;
191 201 }
192 202 else if (ch == '>')
193 203 {
194   - state = st_gt;
  204 + this->m->state = st_gt;
195 205 }
196 206 else
197 207 {
198   - val += ch;
  208 + this->m->val += ch;
199 209 if (ch == ')')
200 210 {
201   - type = tt_bad;
  211 + this->m->type = tt_bad;
202 212 QTC::TC("qpdf", "QPDF_Tokenizer bad )");
203   - error_message = "unexpected )";
204   - state = st_token_ready;
  213 + this->m->error_message = "unexpected )";
  214 + this->m->state = st_token_ready;
205 215 }
206 216 else if (ch == '[')
207 217 {
208   - type = tt_array_open;
209   - state = st_token_ready;
  218 + this->m->type = tt_array_open;
  219 + this->m->state = st_token_ready;
210 220 }
211 221 else if (ch == ']')
212 222 {
213   - type = tt_array_close;
214   - state = st_token_ready;
  223 + this->m->type = tt_array_close;
  224 + this->m->state = st_token_ready;
215 225 }
216 226 else if (ch == '{')
217 227 {
218   - type = tt_brace_open;
219   - state = st_token_ready;
  228 + this->m->type = tt_brace_open;
  229 + this->m->state = st_token_ready;
220 230 }
221 231 else if (ch == '}')
222 232 {
223   - type = tt_brace_close;
224   - state = st_token_ready;
  233 + this->m->type = tt_brace_close;
  234 + this->m->state = st_token_ready;
225 235 }
226 236 else
227 237 {
228   - state = st_literal;
  238 + this->m->state = st_literal;
229 239 }
230 240 }
231 241 }
232   - else if (state == st_in_space)
  242 + else if (this->m->state == st_in_space)
233 243 {
234 244 // We only enter this state if include_ignorable is true.
235 245 if (! isSpace(ch))
236 246 {
237   - type = tt_space;
238   - unread_char = true;
239   - char_to_unread = ch;
240   - state = st_token_ready;
  247 + this->m->type = tt_space;
  248 + this->m->unread_char = true;
  249 + this->m->char_to_unread = ch;
  250 + this->m->state = st_token_ready;
241 251 }
242 252 else
243 253 {
244   - val += ch;
  254 + this->m->val += ch;
245 255 }
246 256 }
247   - else if (state == st_in_comment)
  257 + else if (this->m->state == st_in_comment)
248 258 {
249 259 if ((ch == '\r') || (ch == '\n'))
250 260 {
251   - if (this->include_ignorable)
  261 + if (this->m->include_ignorable)
252 262 {
253   - type = tt_comment;
254   - unread_char = true;
255   - char_to_unread = ch;
256   - state = st_token_ready;
  263 + this->m->type = tt_comment;
  264 + this->m->unread_char = true;
  265 + this->m->char_to_unread = ch;
  266 + this->m->state = st_token_ready;
257 267 }
258 268 else
259 269 {
260   - state = st_top;
  270 + this->m->state = st_top;
261 271 }
262 272 }
263   - else if (this->include_ignorable)
  273 + else if (this->m->include_ignorable)
264 274 {
265   - val += ch;
  275 + this->m->val += ch;
266 276 }
267 277 }
268   - else if (state == st_lt)
  278 + else if (this->m->state == st_lt)
269 279 {
270 280 if (ch == '<')
271 281 {
272   - val = "<<";
273   - type = tt_dict_open;
274   - state = st_token_ready;
  282 + this->m->val = "<<";
  283 + this->m->type = tt_dict_open;
  284 + this->m->state = st_token_ready;
275 285 }
276 286 else
277 287 {
278 288 handled = false;
279   - state = st_in_hexstring;
  289 + this->m->state = st_in_hexstring;
280 290 }
281 291 }
282   - else if (state == st_gt)
  292 + else if (this->m->state == st_gt)
283 293 {
284 294 if (ch == '>')
285 295 {
286   - val = ">>";
287   - type = tt_dict_close;
288   - state = st_token_ready;
  296 + this->m->val = ">>";
  297 + this->m->type = tt_dict_close;
  298 + this->m->state = st_token_ready;
289 299 }
290 300 else
291 301 {
292   - val = ">";
293   - type = tt_bad;
  302 + this->m->val = ">";
  303 + this->m->type = tt_bad;
294 304 QTC::TC("qpdf", "QPDF_Tokenizer bad >");
295   - error_message = "unexpected >";
296   - unread_char = true;
297   - char_to_unread = ch;
298   - state = st_token_ready;
  305 + this->m->error_message = "unexpected >";
  306 + this->m->unread_char = true;
  307 + this->m->char_to_unread = ch;
  308 + this->m->state = st_token_ready;
299 309 }
300 310 }
301   - else if (state == st_in_string)
  311 + else if (this->m->state == st_in_string)
302 312 {
303   - if (string_ignoring_newline && (! ((ch == '\r') || (ch == '\n'))))
  313 + if (this->m->string_ignoring_newline &&
  314 + (! ((ch == '\r') || (ch == '\n'))))
304 315 {
305   - string_ignoring_newline = false;
  316 + this->m->string_ignoring_newline = false;
306 317 }
307 318  
308   - size_t bs_num_count = strlen(bs_num_register);
  319 + size_t bs_num_count = strlen(this->m->bs_num_register);
309 320 bool ch_is_octal = ((ch >= '0') && (ch <= '7'));
310 321 if ((bs_num_count == 3) || ((bs_num_count > 0) && (! ch_is_octal)))
311 322 {
312 323 // We've accumulated \ddd. PDF Spec says to ignore
313 324 // high-order overflow.
314   - val += static_cast<char>(strtol(bs_num_register, 0, 8));
315   - memset(bs_num_register, '\0', sizeof(bs_num_register));
  325 + this->m->val += static_cast<char>(
  326 + strtol(this->m->bs_num_register, 0, 8));
  327 + memset(this->m->bs_num_register, '\0',
  328 + sizeof(this->m->bs_num_register));
316 329 bs_num_count = 0;
317 330 }
318 331  
319   - if (string_ignoring_newline && ((ch == '\r') || (ch == '\n')))
  332 + if (this->m->string_ignoring_newline && ((ch == '\r') || (ch == '\n')))
320 333 {
321 334 // ignore
322 335 }
323   - else if (ch_is_octal && (last_char_was_bs || (bs_num_count > 0)))
  336 + else if (ch_is_octal &&
  337 + (this->m->last_char_was_bs || (bs_num_count > 0)))
324 338 {
325   - bs_num_register[bs_num_count++] = ch;
  339 + this->m->bs_num_register[bs_num_count++] = ch;
326 340 }
327   - else if (last_char_was_bs)
  341 + else if (this->m->last_char_was_bs)
328 342 {
329 343 switch (ch)
330 344 {
331 345 case 'n':
332   - val += '\n';
  346 + this->m->val += '\n';
333 347 break;
334 348  
335 349 case 'r':
336   - val += '\r';
  350 + this->m->val += '\r';
337 351 break;
338 352  
339 353 case 't':
340   - val += '\t';
  354 + this->m->val += '\t';
341 355 break;
342 356  
343 357 case 'b':
344   - val += '\b';
  358 + this->m->val += '\b';
345 359 break;
346 360  
347 361 case 'f':
348   - val += '\f';
  362 + this->m->val += '\f';
349 363 break;
350 364  
351 365 case '\r':
352 366 case '\n':
353   - string_ignoring_newline = true;
  367 + this->m->string_ignoring_newline = true;
354 368 break;
355 369  
356 370 default:
357 371 // PDF spec says backslash is ignored before anything else
358   - val += ch;
  372 + this->m->val += ch;
359 373 break;
360 374 }
361 375 }
... ... @@ -371,22 +385,23 @@ QPDFTokenizer::presentCharacter(char ch)
371 385 }
372 386 else if (ch == '(')
373 387 {
374   - val += ch;
375   - ++string_depth;
  388 + this->m->val += ch;
  389 + ++this->m->string_depth;
376 390 }
377   - else if ((ch == ')') && (--string_depth == 0))
  391 + else if ((ch == ')') && (--this->m->string_depth == 0))
378 392 {
379   - type = tt_string;
380   - state = st_token_ready;
  393 + this->m->type = tt_string;
  394 + this->m->state = st_token_ready;
381 395 }
382 396 else
383 397 {
384   - val += ch;
  398 + this->m->val += ch;
385 399 }
386 400  
387   - last_char_was_bs = ((! last_char_was_bs) && (ch == '\\'));
  401 + this->m->last_char_was_bs =
  402 + ((! this->m->last_char_was_bs) && (ch == '\\'));
388 403 }
389   - else if (state == st_literal)
  404 + else if (this->m->state == st_literal)
390 405 {
391 406 if (strchr(" \t\n\v\f\r()<>[]{}/%", ch) != 0)
392 407 {
... ... @@ -398,14 +413,14 @@ QPDFTokenizer::presentCharacter(char ch)
398 413 // though not on any files in the test suite as of this
399 414 // writing.
400 415  
401   - type = tt_word;
402   - unread_char = true;
403   - char_to_unread = ch;
404   - state = st_token_ready;
  416 + this->m->type = tt_word;
  417 + this->m->unread_char = true;
  418 + this->m->char_to_unread = ch;
  419 + this->m->state = st_token_ready;
405 420 }
406 421 else
407 422 {
408   - val += ch;
  423 + this->m->val += ch;
409 424 }
410 425 }
411 426 else
... ... @@ -418,33 +433,33 @@ QPDFTokenizer::presentCharacter(char ch)
418 433 {
419 434 // okay
420 435 }
421   - else if (state == st_in_hexstring)
  436 + else if (this->m->state == st_in_hexstring)
422 437 {
423 438 if (ch == '>')
424 439 {
425   - type = tt_string;
426   - state = st_token_ready;
427   - if (val.length() % 2)
  440 + this->m->type = tt_string;
  441 + this->m->state = st_token_ready;
  442 + if (this->m->val.length() % 2)
428 443 {
429 444 // PDF spec says odd hexstrings have implicit
430 445 // trailing 0.
431   - val += '0';
  446 + this->m->val += '0';
432 447 }
433 448 char num[3];
434 449 num[2] = '\0';
435 450 std::string nval;
436   - for (unsigned int i = 0; i < val.length(); i += 2)
  451 + for (unsigned int i = 0; i < this->m->val.length(); i += 2)
437 452 {
438   - num[0] = val.at(i);
439   - num[1] = val.at(i+1);
  453 + num[0] = this->m->val.at(i);
  454 + num[1] = this->m->val.at(i+1);
440 455 char nch = static_cast<char>(strtol(num, 0, 16));
441 456 nval += nch;
442 457 }
443   - val = nval;
  458 + this->m->val = nval;
444 459 }
445 460 else if (QUtil::is_hex_digit(ch))
446 461 {
447   - val += ch;
  462 + this->m->val += ch;
448 463 }
449 464 else if (isSpace(ch))
450 465 {
... ... @@ -452,11 +467,11 @@ QPDFTokenizer::presentCharacter(char ch)
452 467 }
453 468 else
454 469 {
455   - type = tt_bad;
  470 + this->m->type = tt_bad;
456 471 QTC::TC("qpdf", "QPDF_Tokenizer bad hexstring character");
457   - error_message = std::string("invalid character (") +
  472 + this->m->error_message = std::string("invalid character (") +
458 473 ch + ") in hexstring";
459   - state = st_token_ready;
  474 + this->m->state = st_token_ready;
460 475 }
461 476 }
462 477 else
... ... @@ -465,61 +480,63 @@ QPDFTokenizer::presentCharacter(char ch)
465 480 "INTERNAL ERROR: invalid state while reading token");
466 481 }
467 482  
468   - if ((state == st_token_ready) && (type == tt_word))
  483 + if ((this->m->state == st_token_ready) && (this->m->type == tt_word))
469 484 {
470 485 resolveLiteral();
471 486 }
472 487  
473   - if (! (betweenTokens() || ((state == st_token_ready) && unread_char)))
  488 + if (! (betweenTokens() ||
  489 + ((this->m->state == st_token_ready) && this->m->unread_char)))
474 490 {
475   - this->raw_val += orig_ch;
  491 + this->m->raw_val += orig_ch;
476 492 }
477 493 }
478 494  
479 495 void
480 496 QPDFTokenizer::presentEOF()
481 497 {
482   - if (state == st_literal)
  498 + if (this->m->state == st_literal)
483 499 {
484 500 QTC::TC("qpdf", "QPDF_Tokenizer EOF reading appendable token");
485 501 resolveLiteral();
486 502 }
487   - else if ((this->include_ignorable) && (state == st_in_space))
  503 + else if ((this->m->include_ignorable) && (this->m->state == st_in_space))
488 504 {
489   - type = tt_space;
  505 + this->m->type = tt_space;
490 506 }
491   - else if ((this->include_ignorable) && (state == st_in_comment))
  507 + else if ((this->m->include_ignorable) && (this->m->state == st_in_comment))
492 508 {
493   - type = tt_comment;
  509 + this->m->type = tt_comment;
494 510 }
495 511 else if (betweenTokens())
496 512 {
497   - type = tt_eof;
  513 + this->m->type = tt_eof;
498 514 }
499   - else if (state != st_token_ready)
  515 + else if (this->m->state != st_token_ready)
500 516 {
501 517 QTC::TC("qpdf", "QPDF_Tokenizer EOF reading token");
502   - type = tt_bad;
503   - error_message = "EOF while reading token";
  518 + this->m->type = tt_bad;
  519 + this->m->error_message = "EOF while reading token";
504 520 }
505 521  
506   - state = st_token_ready;
  522 + this->m->state = st_token_ready;
507 523 }
508 524  
509 525 bool
510 526 QPDFTokenizer::getToken(Token& token, bool& unread_char, char& ch)
511 527 {
512   - bool ready = (this->state == st_token_ready);
513   - unread_char = this->unread_char;
514   - ch = this->char_to_unread;
  528 + bool ready = (this->m->state == st_token_ready);
  529 + unread_char = this->m->unread_char;
  530 + ch = this->m->char_to_unread;
515 531 if (ready)
516 532 {
517   - if (type == tt_bad)
  533 + if (this->m->type == tt_bad)
518 534 {
519   - val = raw_val;
  535 + this->m->val = this->m->raw_val;
520 536 }
521   - token = Token(type, val, raw_val, error_message);
522   - reset();
  537 + token = Token(this->m->type, this->m->val,
  538 + this->m->raw_val, this->m->error_message);
  539 + this->m->reset();
523 540 }
524 541 return ready;
525 542 }
... ... @@ -527,10 +544,10 @@ QPDFTokenizer::getToken(Token&amp; token, bool&amp; unread_char, char&amp; ch)
527 544 bool
528 545 QPDFTokenizer::betweenTokens()
529 546 {
530   - return ((state == st_top) ||
531   - ((! this->include_ignorable) &&
532   - ((state == st_in_comment) ||
533   - (state == st_in_space))));
  547 + return ((this->m->state == st_top) ||
  548 + ((! this->m->include_ignorable) &&
  549 + ((this->m->state == st_in_comment) ||
  550 + (this->m->state == st_in_space))));
534 551 }
535 552  
536 553 QPDFTokenizer::Token
... ... @@ -553,11 +570,11 @@ QPDFTokenizer::readToken(PointerHolder&lt;InputSource&gt; input,
553 570 {
554 571 presentEOF();
555 572 presented_eof = true;
556   - if ((type == tt_eof) && (! this->allow_eof))
  573 + if ((this->m->type == tt_eof) && (! this->m->allow_eof))
557 574 {
558 575 QTC::TC("qpdf", "QPDF_Tokenizer EOF when not allowed");
559   - type = tt_bad;
560   - error_message = "unexpected EOF";
  576 + this->m->type = tt_bad;
  577 + this->m->error_message = "unexpected EOF";
561 578 offset = input->getLastOffset();
562 579 }
563 580 }
... ... @@ -574,14 +591,14 @@ QPDFTokenizer::readToken(PointerHolder&lt;InputSource&gt; input,
574 591 {
575 592 ++offset;
576 593 }
577   - if (max_len && (raw_val.length() >= max_len) &&
578   - (this->state != st_token_ready))
  594 + if (max_len && (this->m->raw_val.length() >= max_len) &&
  595 + (this->m->state != st_token_ready))
579 596 {
580 597 // terminate this token now
581 598 QTC::TC("qpdf", "QPDFTokenizer block long token");
582   - this->type = tt_bad;
583   - this->state = st_token_ready;
584   - error_message =
  599 + this->m->type = tt_bad;
  600 + this->m->state = st_token_ready;
  601 + this->m->error_message =
585 602 "exceeded allowable length while reading token";
586 603 }
587 604 }
... ...