2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-12-22 19:08:59 +00:00

Refactor QPDFTokenizer::inHexstring

This commit is contained in:
m-holger 2022-08-20 13:44:27 +01:00
parent a5d2e88775
commit e4fe0d5cf5
3 changed files with 57 additions and 20 deletions

View File

@ -210,6 +210,7 @@ class QPDFTokenizer
st_gt, st_gt,
st_literal, st_literal,
st_in_hexstring, st_in_hexstring,
st_in_hexstring_2nd,
st_inline_image, st_inline_image,
st_token_ready st_token_ready
}; };
@ -217,6 +218,7 @@ class QPDFTokenizer
void handleCharacter(char); void handleCharacter(char);
void inCharCode(char); void inCharCode(char);
void inHexstring(char); void inHexstring(char);
void inHexstring2nd(char);
void inString(char); void inString(char);
void reset(); void reset();
@ -238,6 +240,7 @@ class QPDFTokenizer
// State for strings // State for strings
int string_depth; int string_depth;
int char_code;
char bs_num_register[4]; char bs_num_register[4];
}; };

View File

@ -442,6 +442,10 @@ QPDFTokenizer::handleCharacter(char ch)
inHexstring(ch); inHexstring(ch);
return; return;
case (st_in_hexstring_2nd):
inHexstring2nd(ch);
return;
default: default:
throw std::logic_error( throw std::logic_error(
"INTERNAL ERROR: invalid state while reading token"); "INTERNAL ERROR: invalid state while reading token");
@ -451,29 +455,25 @@ QPDFTokenizer::handleCharacter(char ch)
void void
QPDFTokenizer::inHexstring(char ch) QPDFTokenizer::inHexstring(char ch)
{ {
if (ch == '>') { if ('0' <= ch && ch <= '9') {
this->char_code = 16 * (int(ch) - int('0'));
this->state = st_in_hexstring_2nd;
} else if ('A' <= ch && ch <= 'F') {
this->char_code = 16 * (10 + int(ch) - int('A'));
this->state = st_in_hexstring_2nd;
} else if ('a' <= ch && ch <= 'f') {
this->char_code = 16 * (10 + int(ch) - int('a'));
this->state = st_in_hexstring_2nd;
} else if (ch == '>') {
this->type = tt_string; this->type = tt_string;
this->state = st_token_ready; this->state = st_token_ready;
if (this->val.length() % 2) {
// PDF spec says odd hexstrings have implicit
// trailing 0.
this->val += '0';
}
char num[3];
num[2] = '\0';
std::string nval;
for (unsigned int i = 0; i < this->val.length(); i += 2) {
num[0] = this->val.at(i);
num[1] = this->val.at(i + 1);
char nch = static_cast<char>(strtol(num, nullptr, 16));
nval += nch;
}
this->val.clear();
this->val += nval;
} else if (QUtil::is_hex_digit(ch)) {
this->val += ch;
} else if (isSpace(ch)) { } else if (isSpace(ch)) {
// ignore // ignore
} else { } else {
this->type = tt_bad; this->type = tt_bad;
QTC::TC("qpdf", "QPDFTokenizer bad hexstring character"); QTC::TC("qpdf", "QPDFTokenizer bad hexstring character");
@ -483,6 +483,39 @@ QPDFTokenizer::inHexstring(char ch)
} }
} }
void
QPDFTokenizer::inHexstring2nd(char ch)
{
if ('0' <= ch && ch <= '9') {
this->val += char(this->char_code + int(ch) - int('0'));
this->state = st_in_hexstring;
} else if ('A' <= ch && ch <= 'F') {
this->val += char(this->char_code + 10 + int(ch) - int('A'));
this->state = st_in_hexstring;
} else if ('a' <= ch && ch <= 'f') {
this->val += char(this->char_code + 10 + int(ch) - int('a'));
this->state = st_in_hexstring;
} else if (ch == '>') {
// PDF spec says odd hexstrings have implicit trailing 0.
this->val += char(this->char_code);
this->type = tt_string;
this->state = st_token_ready;
} else if (isSpace(ch)) {
// ignore
} else {
this->type = tt_bad;
QTC::TC("qpdf", "QPDFTokenizer bad hexstring 2nd character");
this->error_message =
std::string("invalid character (") + ch + ") in hexstring";
this->state = st_token_ready;
}
}
void void
QPDFTokenizer::inString(char ch) QPDFTokenizer::inString(char ch)
{ {
@ -526,7 +559,7 @@ void
QPDFTokenizer::inCharCode(char ch) QPDFTokenizer::inCharCode(char ch)
{ {
size_t bs_num_count = strlen(this->bs_num_register); size_t bs_num_count = strlen(this->bs_num_register);
bool ch_is_octal = ((ch >= '0') && (ch <= '7')); bool ch_is_octal = ('0' <= ch && ch <= '7');
if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) { if ((bs_num_count == 3) || ((bs_num_count > 0) && (!ch_is_octal))) {
// We've accumulated \ddd. PDF Spec says to ignore // We've accumulated \ddd. PDF Spec says to ignore
// high-order overflow. // high-order overflow.

View File

@ -66,6 +66,7 @@ QPDF can't find xref 0
QPDFTokenizer bad ) 0 QPDFTokenizer bad ) 0
QPDFTokenizer bad > 0 QPDFTokenizer bad > 0
QPDFTokenizer bad hexstring character 0 QPDFTokenizer bad hexstring character 0
QPDFTokenizer bad hexstring 2nd character 0
QPDFTokenizer null in name 0 QPDFTokenizer null in name 0
QPDFTokenizer bad name 0 QPDFTokenizer bad name 0
QPDF_Stream invalid filter 0 QPDF_Stream invalid filter 0