Coverage Report

Created: 2026-01-25 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qpdf/libqpdf/ContentNormalizer.cc
Line
Count
Source
1
#include <qpdf/ContentNormalizer.hh>
2
3
#include <qpdf/QPDFObjectHandle_private.hh>
4
#include <qpdf/QUtil.hh>
5
6
using namespace qpdf;
7
8
void
9
ContentNormalizer::handleToken(QPDFTokenizer::Token const& token)
10
84.8M
{
11
84.8M
    QPDFTokenizer::token_type_e token_type = token.getType();
12
13
84.8M
    if (token_type == QPDFTokenizer::tt_bad) {
14
3.27M
        this->any_bad_tokens = true;
15
3.27M
        this->last_token_was_bad = true;
16
81.5M
    } else if (token_type != QPDFTokenizer::tt_eof) {
17
81.5M
        this->last_token_was_bad = false;
18
81.5M
    }
19
20
84.8M
    switch (token_type) {
21
35.9M
    case QPDFTokenizer::tt_space:
22
35.9M
        {
23
35.9M
            std::string const& value = token.getRawValue();
24
35.9M
            auto size = value.size();
25
35.9M
            size_t pos = 0;
26
35.9M
            auto r_pos = value.find('\r');
27
41.1M
            while (r_pos != std::string::npos) {
28
5.71M
                if (pos != r_pos) {
29
4.58M
                    write(&value[pos], r_pos - pos);
30
4.58M
                }
31
5.71M
                if (++r_pos >= size) {
32
469k
                    write("\n");
33
469k
                    return;
34
469k
                }
35
5.24M
                if (value[r_pos] != '\n') {
36
5.23M
                    write("\n");
37
5.23M
                }
38
5.24M
                pos = r_pos;
39
5.24M
                r_pos = value.find('\r', pos);
40
5.24M
            }
41
35.4M
            if (pos < size) {
42
35.4M
                write(&value[pos], size - pos);
43
35.4M
            }
44
35.4M
        }
45
0
        return;
46
47
234k
    case QPDFTokenizer::tt_string:
48
        // Replacing string and name tokens in this way normalizes their representation as this will
49
        // automatically handle quoting of unprintable characters, etc.
50
234k
        write(QPDFObjectHandle::newString(token.getValue()).unparse());
51
234k
        break;
52
53
1.28M
    case QPDFTokenizer::tt_name:
54
1.28M
        write(Name::normalize(token.getValue()));
55
1.28M
        break;
56
57
47.4M
    default:
58
47.4M
        writeToken(token);
59
47.4M
        return;
60
84.8M
    }
61
62
    // tt_string or tt_name
63
1.51M
    std::string const& value = token.getRawValue();
64
1.51M
    if (value.find('\r') != std::string::npos || value.find('\n') != std::string::npos) {
65
46.6k
        write("\n");
66
46.6k
    }
67
1.51M
}