summaryrefslogtreecommitdiff
path: root/src/pdf_doc.c
blob: dd31b728108e0022b8dcc120b04df08f9e3b6074 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#include "nspdferror.h"
#include "byte_class.h"
#include "cos_object.h"
#include "pdf_doc.h"

/**
 * move offset to next non whitespace byte
 */
nspdferror doc_skip_ws(struct pdf_doc *doc, uint64_t *offset)
{
    uint8_t c;
    /* TODO sort out keeping offset in range */
    c = DOC_BYTE(doc, *offset);
    while ((bclass[c] & (BC_WSPC | BC_CMNT) ) != 0) {
        (*offset)++;
        /* skip comments */
        if ((bclass[c] & BC_CMNT) != 0) {
            c = DOC_BYTE(doc, *offset);
            while ((bclass[c] & BC_EOLM ) == 0) {
                (*offset)++;
                c = DOC_BYTE(doc, *offset);
            }
        }
        c = DOC_BYTE(doc, *offset);
    }
    return NSPDFERROR_OK;
}

/**
 * move offset to next non eol byte
 */
nspdferror doc_skip_eol(struct pdf_doc *doc, uint64_t *offset)
{
    uint8_t c;
    /* TODO sort out keeping offset in range */
    c = DOC_BYTE(doc, *offset);
    while ((bclass[c] & BC_EOLM) != 0) {
        (*offset)++;
        c = DOC_BYTE(doc, *offset);
    }
    return NSPDFERROR_OK;
}

static struct cos_object cos_null_obj = {
    .type = COS_TYPE_NULL,
};

nspdferror
xref_get_referenced(struct pdf_doc *doc, struct cos_object **cobj_out)
{
    nspdferror res;
    struct cos_object *cobj;
    struct cos_object *indirect;
    uint64_t offset;
    struct xref_table_entry *entry;

    cobj = *cobj_out;

    if (cobj->type != COS_TYPE_REFERENCE) {
        /* not passed a reference object so just return what was passed */
        return NSPDFERROR_OK;
    }

    entry = doc->xref_table + cobj->u.reference->id;

    /* check if referenced object is in range and exists. return null object if
     * not
     */
    if ((cobj->u.reference->id >= doc->xref_size) ||
        (cobj->u.reference->id == 0) ||
        (entry->ref.id == 0)) {
        *cobj_out = &cos_null_obj;
        return NSPDFERROR_OK;
    }

    if (entry->object == NULL) {
        /* indirect object has never been decoded */
        offset = entry->offset;
        res = cos_decode_object(doc, &offset, &indirect);
        if (res != NSPDFERROR_OK) {
            return res;
        }

        entry->object = indirect;
    }

    cobj = entry->object;

    return NSPDFERROR_OK;
}