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

documentation of the auxiliary module

parent 0a209460
Loading
Loading
Loading
Loading
+116 −4
Original line number Diff line number Diff line
@@ -24,14 +24,14 @@
 */
void sigil_zeroize(void *a, size_t bytes);

/** @brief Decide whether the character is a digit
/** @brief Decides whether the character is a digit
 *
 * @param c character provided for comparison
 * @return 1 if true, 0 otherwise
 */
int is_digit(const char c);

/** @brief Decide whether the character is a whitespace according to PDF standard
/** @brief Decides whether the character is a whitespace according to PDF standard
 *
 * @param c character provided for comparison
 * @return 1 if true, 0 otherwise
@@ -98,27 +98,139 @@ sigil_err_t pdf_goto_obj(sigil_t *sgl, reference_t *ref);
 */
sigil_err_t get_curr_position(sigil_t *sgl, size_t *result);

/** @brief Move position in the PDF forward to the first non-whitespace character
 *         from the current position
 *
 * @param sgl context
 * @return ERR_NONE if success
 */
sigil_err_t skip_leading_whitespaces(sigil_t *sgl);

/** @brief Move position in the PDF after the array from the current position.
 *         The initial position needs to be after the leading '[' character
 *
 * @param sgl context
 * @return ERR_NONE if success
 */
sigil_err_t skip_array(sigil_t *sgl);

/** @brief Move position in the PDF after the dictionary from the current position.
 *         The initial position needs to be after the leading "<<" characters
 *
 * @param sgl context
 * @return ERR_NONE if success
 */
sigil_err_t skip_dictionary(sigil_t *sgl);

/** @brief Move position in the PDF after the value (pairs of key-value) inside
 *         of the dictionary from the current position
 *
 * @param sgl context
 * @return ERR_NONE if success
 */
sigil_err_t skip_dict_unknown_value(sigil_t *sgl);

/** @brief Move position in the PDF after the specified word that needs to start
 *         from the current possition (leading whitespaces are allowed)
 *
 * @param sgl context
 * @param word move position after this word
 * @return ERR_NONE if success
 */
sigil_err_t skip_word(sigil_t *sgl, const char *word);

/** @brief Loads a number from the current position in the PDF
 *
 * @param sgl context
 * @param number output - loaded number
 * @return ERR_NONE if success
 */
sigil_err_t parse_number(sigil_t *sgl, size_t *number);
sigil_err_t parse_word(sigil_t *sgl, const char *word);

/** @brief Loads an indirect reference from the current position in the PDF
 *
 * @param sgl context
 * @param ref output - indirect reference loaded
 * @return ERR_NONE if success
 */
sigil_err_t parse_indirect_reference(sigil_t *sgl, reference_t *ref);

/** @brief Loads a dictionary key from the current position in the PDF
 *
 * @param sgl context
 * @param dict_key output - loaded key
 * @return ERR_NONE if success
 */
sigil_err_t parse_dict_key(sigil_t *sgl, dict_key_t *dict_key);

/** @brief Loads an array of indirect references from the current position in
 *         the PDF. The leading '[' needs to be included
 *
 * @param sgl context
 * @param ref_array output - the loaded array of indirect references
 * @return ERR_NONE if success
 */
sigil_err_t parse_ref_array(sigil_t *sgl, ref_array_t *ref_array);

/** @brief Resolves the offset of an object according to the xref section
 *
 * @param sgl context
 * @param ref input - indirect reference to be resolved
 * @param result output - the byte offset
 * @return ERR_NONE if success
 */
sigil_err_t reference_to_offset(sigil_t *sgl, const reference_t *ref, size_t *result);

/** @brief Print the module name, according to the verbosity level set
 *
 * @param module_name name of the module to be printed
 * @param verbosity with values >= 1 the output is printed
 */
void print_module_name(const char *module_name, int verbosity);

/** @brief Print nicely the overall results of the tested module
 *
 * @param result value 1 means the module passed all the tests, 0 means it failed
 * @param verbosity with values >= 1 the output is printed
 */
void print_module_result(int result, int verbosity);

/** @brief Print the name of a test inside of a module
 *
 * @param test_name the name to be printed
 * @param verbosity with values >= 2 the output is printed
 */
void print_test_item(const char *test_name, int verbosity);

/** @brief Print the result of one test inside of a module
 *
 * @param result value 1 means the test succeeded, 0 means it failed
 * @param verbosity with values >= 2 the output is printed
 */
void print_test_result(int result, int verbosity);

sigil_t *test_prepare_sgl_content(char *content, size_t size);
/** @brief Prepares context for the tests from the provided buffer and size
 *
 * @param content the PDF data
 * @param size number of bytes of the content
 * @return valid sigil_t context if succeeded, NULL if failed
 */
sigil_t *test_prepare_sgl_buffer(char *content, size_t size);

/** @brief Prepares context for the tests from a file specified by filepath
 *
 * @param path the PDF filepath
 * @return valid sigil_t context if succeeded, NULL if failed
 */
sigil_t *test_prepare_sgl_path(const char *path);

/** @brief Tests for the auxiliary module
 *
 * @param verbosity output level - 0 means nothing, 1 prints module names with
 *                  the overall module result, and 2 prints also each test inside
 *                  of the module
 * @return 0 if success, 1 if failed
 */
int sigil_auxiliary_self_test(int verbosity);

#endif /* PDF_SIGIL_AUXILIARY_H */
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ sigil_err_t process_acroform(sigil_t *sgl)
            return err;
    }

    err = parse_word(sgl, "<<");
    err = skip_word(sgl, "<<");
    if (err != ERR_NONE)
        return err;

+47 −48
Original line number Diff line number Diff line
@@ -134,8 +134,6 @@ sigil_err_t pdf_peek_char(sigil_t *sgl, char *result)
    return ERR_NO_DATA;
}

// shifts position relatively to current position in boundaries between
//   beginning of file and end of file
sigil_err_t pdf_move_pos_rel(sigil_t *sgl, ssize_t shift_bytes)
{
    ssize_t final_position;
@@ -232,7 +230,7 @@ sigil_err_t pdf_goto_obj(sigil_t *sgl, reference_t *ref)
    if (tmp != ref->generation_num)
        return ERR_PDF_CONTENT;

    err = parse_word(sgl, "obj");
    err = skip_word(sgl, "obj");
    if (err != ERR_NONE)
        return err;

@@ -310,7 +308,6 @@ sigil_err_t skip_array(sigil_t *sgl)
    return err;
}

// without leading "<<"
sigil_err_t skip_dictionary(sigil_t *sgl)
{
    sigil_err_t err;
@@ -400,6 +397,37 @@ sigil_err_t skip_dict_unknown_value(sigil_t *sgl)
    return err;
}

sigil_err_t skip_word(sigil_t *sgl, const char *word)
{
    sigil_err_t err;
    size_t length;
    char c;

    if (sgl == NULL || word == NULL)
        return ERR_PARAMETER;

    err = skip_leading_whitespaces(sgl);
    if (err != ERR_NONE)
        return err;

    length = strlen(word);

    for (size_t pos = 0; pos < length; pos++) {
        err = pdf_peek_char(sgl, &c);
        if (err != ERR_NONE)
            return err;

        if (c != word[pos])
            return ERR_PDF_CONTENT;

        err = pdf_move_pos_rel(sgl, 1);
        if (err != ERR_NONE)
            return err;
    }

    return ERR_NONE;
}

sigil_err_t parse_number(sigil_t *sgl, size_t *number)
{
    sigil_err_t err;
@@ -436,37 +464,6 @@ sigil_err_t parse_number(sigil_t *sgl, size_t *number)
    return err;
}

sigil_err_t parse_word(sigil_t *sgl, const char *word)
{
    sigil_err_t err;
    size_t length;
    char c;

    if (sgl == NULL || word == NULL)
        return ERR_PARAMETER;

    err = skip_leading_whitespaces(sgl);
    if (err != ERR_NONE)
        return err;

    length = strlen(word);

    for (size_t pos = 0; pos < length; pos++) {
        err = pdf_peek_char(sgl, &c);
        if (err != ERR_NONE)
            return err;

        if (c != word[pos])
            return ERR_PDF_CONTENT;

        err = pdf_move_pos_rel(sgl, 1);
        if (err != ERR_NONE)
            return err;
    }

    return ERR_NONE;
}

sigil_err_t parse_indirect_reference(sigil_t *sgl, reference_t *ref)
{
    sigil_err_t err;
@@ -479,7 +476,7 @@ sigil_err_t parse_indirect_reference(sigil_t *sgl, reference_t *ref)
    if (err != ERR_NONE)
        return err;

    err = parse_word(sgl, "R");
    err = skip_word(sgl, "R");
    if (err != ERR_NONE)
        return err;

@@ -499,10 +496,10 @@ sigil_err_t parse_dict_key(sigil_t *sgl, dict_key_t *dict_key)

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

    if (parse_word(sgl, ">>") == ERR_NONE)
    if (skip_word(sgl, ">>") == ERR_NONE)
        return ERR_END_OF_DICT;

    err = parse_word(sgl, "/");
    err = skip_word(sgl, "/");
    if (err != ERR_NONE)
        return err;

@@ -554,6 +551,8 @@ sigil_err_t parse_dict_key(sigil_t *sgl, dict_key_t *dict_key)
        *dict_key = DICT_KEY_UNKNOWN;
    }

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

    return ERR_NONE;
}

@@ -567,10 +566,10 @@ sigil_err_t parse_ref_array(sigil_t *sgl, ref_array_t *ref_array)
    if (sgl == NULL || ref_array == NULL)
        return ERR_PARAMETER;

    if ((err = parse_word(sgl, "[")) != ERR_NONE)
    if ((err = skip_word(sgl, "[")) != ERR_NONE)
        return err;

    if (parse_word(sgl, "]") == ERR_NONE) // empty array
    if (skip_word(sgl, "]") == ERR_NONE) // empty array
        return ERR_NONE;

    if (ref_array->capacity <= 0) {
@@ -606,7 +605,7 @@ sigil_err_t parse_ref_array(sigil_t *sgl, ref_array_t *ref_array)
        ref_array->entry[position]->object_num = reference.object_num;
        ref_array->entry[position]->generation_num = reference.generation_num;

        if (parse_word(sgl, "]") == ERR_NONE)
        if (skip_word(sgl, "]") == ERR_NONE)
            return ERR_NONE;

        position++;
@@ -679,7 +678,7 @@ void print_test_result(int result, int verbosity)
    }
}

sigil_t *test_prepare_sgl_content(char *content, size_t size)
sigil_t *test_prepare_sgl_buffer(char *content, size_t size)
{
    sigil_t *sgl;

@@ -791,7 +790,7 @@ int sigil_auxiliary_self_test(int verbosity)
        size_t output_size;

        char *sstream = "abbbcx";
        if ((sgl = test_prepare_sgl_content(sstream, strlen(sstream) + 1)) == NULL)
        if ((sgl = test_prepare_sgl_buffer(sstream, strlen(sstream) + 1)) == NULL)
            goto failed;

        if (pdf_read(sgl, 5, output, &output_size) != ERR_NONE ||
@@ -812,7 +811,7 @@ int sigil_auxiliary_self_test(int verbosity)
    print_test_item("fn skip_leading_whitespaces", verbosity);

    {
        if ((sgl = test_prepare_sgl_content("x", 2)) == NULL)
        if ((sgl = test_prepare_sgl_buffer("x", 2)) == NULL)
            goto failed;

        if (skip_leading_whitespaces(sgl) != ERR_NONE)
@@ -823,7 +822,7 @@ int sigil_auxiliary_self_test(int verbosity)

        sigil_free(&sgl);

        if ((sgl = test_prepare_sgl_content("\x00\x09\x0a\x0c\x0d\x20x", 8)) == NULL)
        if ((sgl = test_prepare_sgl_buffer("\x00\x09\x0a\x0c\x0d\x20x", 8)) == NULL)
            goto failed;

        if (skip_leading_whitespaces(sgl) != ERR_NONE)
@@ -846,7 +845,7 @@ int sigil_auxiliary_self_test(int verbosity)
                        "/Third true "          \
                        "/Fourth [<86C><BA3>] " \
                        ">>x";
        if ((sgl = test_prepare_sgl_content(sstream, strlen(sstream) + 1)) == NULL)
        if ((sgl = test_prepare_sgl_buffer(sstream, strlen(sstream) + 1)) == NULL)
            goto failed;

        if (skip_dictionary(sgl) != ERR_NONE)
@@ -867,7 +866,7 @@ int sigil_auxiliary_self_test(int verbosity)
        char *sstream = "<</First /NameVal\n"    \
                        "/Second <</Nested -32 " \
                        ">> >>x";
        if ((sgl = test_prepare_sgl_content(sstream, strlen(sstream) + 1)) == NULL)
        if ((sgl = test_prepare_sgl_buffer(sstream, strlen(sstream) + 1)) == NULL)
            goto failed;

        if (skip_dict_unknown_value(sgl) != ERR_NONE)
@@ -888,7 +887,7 @@ int sigil_auxiliary_self_test(int verbosity)
        size_t result = 0;

        char *sstream = "0123456789    42";
        if ((sgl = test_prepare_sgl_content(sstream, strlen(sstream) + 1)) == NULL)
        if ((sgl = test_prepare_sgl_buffer(sstream, strlen(sstream) + 1)) == NULL)
            goto failed;

        if (parse_number(sgl, &result) != ERR_NONE || result != 123456789)
+2 −2
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ sigil_err_t process_catalog_dictionary(sigil_t *sgl)
    if (err != ERR_NONE)
        return err;

    err = parse_word(sgl, "<<");
    err = skip_word(sgl, "<<");
    if (err != ERR_NONE)
        return err;

@@ -43,7 +43,7 @@ sigil_err_t process_catalog_dictionary(sigil_t *sgl)

                    sgl->offset_acroform = offset;

                    if ((err = parse_word(sgl, "<<")) != ERR_NONE)
                    if ((err = skip_word(sgl, "<<")) != ERR_NONE)
                        return err;

                    err = skip_dictionary(sgl);
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ sigil_err_t parse_one_cert(sigil_t *sgl, cert_t **result)
        *result = NULL;
    }

    if ((err = parse_word(sgl, "<")) != ERR_NONE)
    if ((err = skip_word(sgl, "<")) != ERR_NONE)
        return err;

    *result = malloc(sizeof(**result));
Loading