Verified Commit 0b8c58ce authored by Tomáš Stefan's avatar Tomáš Stefan
Browse files

Initial support for processing trailer

parent 585c1735
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -24,12 +24,30 @@
    typedef uint32_t free_indicator_t;
#endif /* FREE_INDICATOR_T */

#ifndef REREFENCE_T
#define REREFENCE_T
    typedef struct {
        size_t object_num;
        size_t generation_num;
    } reference_t;
#endif /* REREFENCE_T */

#ifndef DICT_KEY_T
#define DICT_KEY_T
    typedef uint32_t dict_key_t;
#endif /* DICT_KEY_T */

#define KEYWORD_xref     0
#define KEYWORD_trailer  1

#define IN_USE_ENTRY     0
#define FREE_ENTRY       1

#define DICT_KEY_Size      0
#define DICT_KEY_Prev      1
#define DICT_KEY_Root      2
#define DICT_KEY_unknown   3

#define COLOR_RED        "\x1b[31m"
#define COLOR_GREEN      "\x1b[32m"
#define COLOR_RESET      "\x1b[0m"
@@ -44,10 +62,14 @@ int is_digit(const char_t c);
int is_whitespace(const char_t c);

sigil_err_t skip_leading_whitespaces(FILE *in);
sigil_err_t skip_dictionary(FILE *in);
sigil_err_t skip_dict_unknown_value(FILE *in);

sigil_err_t parse_number(FILE *in, size_t *number);
sigil_err_t parse_keyword(FILE *in, keyword_t *keyword);
sigil_err_t parse_free_indicator(FILE *in, free_indicator_t *result);
sigil_err_t parse_indirect_reference(FILE *in, reference_t *ref);
sigil_err_t parse_dict_key(FILE *in, dict_key_t *dict_key);

void print_module_name(const char *module_name, int verbosity);
void print_module_result(int result, int verbosity);
+19 −8
Original line number Diff line number Diff line
@@ -23,9 +23,19 @@
    typedef struct {
        xref_entry_t **entry;
        size_t capacity;
        size_t size_from_trailer;
        size_t prev_section;
    } xref_t;
#endif /* XREF_T */

#ifndef REREFENCE_T
#define REREFENCE_T
    typedef struct {
        size_t object_num;
        size_t generation_num;
    } reference_t;
#endif /* REREFENCE_T */

#define XREF_TYPE_UNSET    0
#define XREF_TYPE_TABLE    1
#define XREF_TYPE_STREAM   2
@@ -36,6 +46,7 @@ typedef struct {
                pdf_y;             /*   %PDF-<pdf_x>.<pdf_y>  */
    short       xref_type;
    xref_t     *xref;
    reference_t ref_catalog_dict;
    size_t      file_size;
    size_t      pdf_start_offset;  /* offset of %PDF-x.y      */
    size_t      startxref;
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
    typedef struct {
        xref_entry_t **entry;
        size_t capacity;
        size_t size_from_trailer;
        size_t prev_section;
    } xref_t;
#endif /* XREF_T */

+135 −0
Original line number Diff line number Diff line
@@ -47,6 +47,60 @@ sigil_err_t skip_leading_whitespaces(FILE *in)
    return (sigil_err_t)ERR_NO;
}

sigil_err_t skip_dictionary(FILE *in)
{
    sigil_err_t err;
    char c;

    err = skip_leading_whitespaces(in);
    if (err != ERR_NO)
        return err;

    while ((c = fgetc(in)) != EOF) {
        switch (c) {
            case '>':
                if (fgetc(in) == '>')
                    return (sigil_err_t)ERR_NO;
                break;
            case '<':
                if (fgetc(in) != '<')
                    break;
                if ((err = skip_dictionary(in)) != ERR_NO)
                    return err;
                return (sigil_err_t)ERR_NO;
            default:
                break;
        }
    }

    return (sigil_err_t)ERR_PDF_CONT;
}

sigil_err_t skip_dict_unknown_value(FILE *in)
{
    sigil_err_t err;
    char c;

    while ((c = fgetc(in)) != EOF) {
        switch (c) {
            case '/':
                if (ungetc(c, in) != c)
                    return (sigil_err_t)ERR_IO;
                return (sigil_err_t)ERR_NO;
            case '<':
                if (fgetc(in) != '<')
                    break;
                if ((err = skip_dictionary(in)) != ERR_NO)
                    return err;
                return (sigil_err_t)ERR_NO;
            default:
                break;
        }
    }

    return (sigil_err_t)ERR_PDF_CONT;
}

sigil_err_t parse_number(FILE *in, size_t *number)
{
    char_t c;
@@ -141,6 +195,87 @@ sigil_err_t parse_free_indicator(FILE *in, free_indicator_t *result)
    }
}

sigil_err_t parse_indirect_reference(FILE *in, reference_t *ref)
{
    sigil_err_t err;

    err = parse_number(in, &ref->object_num);
    if (err != ERR_NO)
        return err;
    err = parse_number(in, &ref->generation_num);
    if (err != ERR_NO)
        return err;
    err = skip_leading_whitespaces(in);
    if (err != ERR_NO)
        return err;
    if (fgetc(in) != 'R')
        return (sigil_err_t)ERR_PDF_CONT;
    return (sigil_err_t)ERR_NO;
}

// parse the key of the couple key - value in the dictionary
sigil_err_t parse_dict_key(FILE *in, dict_key_t *dict_key)
{
    sigil_err_t err;
    const int dict_key_max = 10;
    int count = 0;
    char tmp[dict_key_max],
         c;

    sigil_zeroize(tmp, dict_key_max * sizeof(*tmp));

    err = skip_leading_whitespaces(in);
    if (err != ERR_NO)
        return err;

    if ((c = fgetc(in)) == EOF)
        return 1;

    switch (c) {
        case '/':
            break;
        case '>':
            if ((c = fgetc(in)) == '>')
                return (sigil_err_t)ERR_PDF_CONT;
            if (ungetc(c, in) != c)
                return (sigil_err_t)ERR_IO;
            return (sigil_err_t)ERR_PDF_CONT;
        default:
            return (sigil_err_t)ERR_PDF_CONT;
    }

    while ((c = fgetc(in)) != EOF) {
        if (is_whitespace(c)) {
            if (count <= 0)
                return (sigil_err_t)ERR_PDF_CONT;
            if (ungetc(c, in) != c)
                return (sigil_err_t)ERR_IO;

            if (strncmp(tmp, "Size", 4) == 0) {
                *dict_key = DICT_KEY_Size;
                return (sigil_err_t)ERR_NO;
            }
            if (strncmp(tmp, "Prev", 4) == 0) {
                *dict_key = DICT_KEY_Prev;
                return (sigil_err_t)ERR_NO;
            }
            if (strncmp(tmp, "Root", 4) == 0) {
                *dict_key = DICT_KEY_Root;
                return (sigil_err_t)ERR_NO;
            }
            *dict_key = DICT_KEY_unknown;
            return (sigil_err_t)ERR_NO;
        } else {
            if (count >= dict_key_max - 1)
                return (sigil_err_t)ERR_ALLOC;
            tmp[count] = c;
            count++;
        }
    }

    return (sigil_err_t)ERR_PDF_CONT;
}

void print_module_name(const char *module_name, int verbosity)
{
    if (verbosity < 1)
+10 −8
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ sigil_err_t sigil_init(sigil_t **sgl)
    (*sgl)->pdf_y                           = 0;
    (*sgl)->xref_type                       = XREF_TYPE_UNSET;
    (*sgl)->xref                            = NULL;
    (*sgl)->ref_catalog_dict.object_num     = 0;
    (*sgl)->ref_catalog_dict.generation_num = 0;
    (*sgl)->file_size                       = 0;
    (*sgl)->pdf_start_offset                = 0;
    (*sgl)->startxref                       = 0;
Loading