Commit c612d4e3 authored by Tomáš Stefan's avatar Tomáš Stefan

documentation of the auxiliary module

parent 0a209460
......@@ -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 */
......@@ -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;
......
......@@ -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)
......
......@@ -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);
......
......@@ -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));
......
......@@ -24,7 +24,7 @@ sigil_err_t parse_contents(sigil_t *sgl)
if (sgl->contents != NULL)
contents_free(sgl);
if ((err = parse_word(sgl, "<")) != ERR_NONE)
if ((err = skip_word(sgl, "<")) != ERR_NONE)
return err;
sgl->contents = malloc(sizeof(*(sgl->contents)));
......
......@@ -72,7 +72,7 @@ int sigil_header_self_test(int verbosity)
{
char *sstream_1 = "\x25PDF-1.1 x";
if ((sgl = test_prepare_sgl_content(sstream_1, strlen(sstream_1) + 1)) == NULL)
if ((sgl = test_prepare_sgl_buffer(sstream_1, strlen(sstream_1) + 1)) == NULL)
goto failed;
if (process_header(sgl) != ERR_NONE ||
......@@ -95,7 +95,7 @@ int sigil_header_self_test(int verbosity)
"\xd3\x8c\x0f\xc0\x43\x1a\xa5\x07\x4f\xe2\x98\xb3\xd8"\
"\x53\x4b\x5d\x4b\xd6\x48\x26\x98\x09\xde\x0d" \
"\x25PDF-1.2 x";
if ((sgl = test_prepare_sgl_content(sstream_2, strlen(sstream_2) + 1)) == NULL)
if ((sgl = test_prepare_sgl_buffer(sstream_2, strlen(sstream_2) + 1)) == NULL)
goto failed;
if (process_header(sgl) != ERR_NONE ||
......
......@@ -23,7 +23,7 @@ static sigil_err_t parse_subfilter(sigil_t *sgl)
sigil_zeroize(tmp, SUBFILTER_MAX * sizeof(*tmp));
err = parse_word(sgl, "/");
err = skip_word(sgl, "/");
if (err != ERR_NONE)
return err;
......@@ -64,14 +64,14 @@ static sigil_err_t parse_byte_range(sigil_t *sgl)
if (sgl == NULL)
return ERR_PARAMETER;
err = parse_word(sgl, "[");
err = skip_word(sgl, "[");
if (err != ERR_NONE)
return err;
byte_range = &(sgl->byte_range);
while (1) {
if (parse_word(sgl, "]") == ERR_NONE)
if (skip_word(sgl, "]") == ERR_NONE)
return ERR_NONE;
err = parse_number(sgl, &start);
......@@ -117,7 +117,7 @@ sigil_err_t process_sig_dict(sigil_t *sgl)
return err;
}
err = parse_word(sgl, "<<");
err = skip_word(sgl, "<<");
if (err != ERR_NONE)
return err;
......
......@@ -23,7 +23,7 @@ sigil_err_t find_sig_field(sigil_t *sgl)
if (err != ERR_NONE)
return err;
err = parse_word(sgl, "<<");
err = skip_word(sgl, "<<");
if (err != ERR_NONE)
return err;
......@@ -32,7 +32,7 @@ sigil_err_t find_sig_field(sigil_t *sgl)
while (!other_ft && (err = parse_dict_key(sgl, &dict_key)) == ERR_NONE) {
switch (dict_key) {
case DICT_KEY_FT:
if (parse_word(sgl, "/Sig") == ERR_NONE) {
if (skip_word(sgl, "/Sig") == ERR_NONE) {
sgl->ref_sig_field = *(sgl->fields.entry[i]);
return ERR_NONE;
} else {
......@@ -70,14 +70,14 @@ sigil_err_t process_sig_field(sigil_t *sgl)
if (err != ERR_NONE)
return err;
err = parse_word(sgl, "<<");
err = skip_word(sgl, "<<");
if (err != ERR_NONE)
return err;
while ((err = parse_dict_key(sgl, &dict_key)) == ERR_NONE) {
switch (dict_key) {
case DICT_KEY_FT:
if (parse_word(sgl, "/Sig") != ERR_NONE)
if (skip_word(sgl, "/Sig") != ERR_NONE)
return ERR_PDF_CONTENT;
break;
case DICT_KEY_V:
......@@ -91,7 +91,7 @@ sigil_err_t process_sig_field(sigil_t *sgl)
sgl->offset_sig_dict = offset;
if ((err = parse_word(sgl, "<<")) != ERR_NONE)
if ((err = skip_word(sgl, "<<")) != ERR_NONE)
return err;
err = skip_dictionary(sgl);
......
......@@ -11,11 +11,11 @@ sigil_err_t process_trailer(sigil_t *sgl)
if (sgl == NULL)
return ERR_PARAMETER;
err = parse_word(sgl, "trailer");
err = skip_word(sgl, "trailer");
if (err != ERR_NONE)
return err;
err = parse_word(sgl, "<<");
err = skip_word(sgl, "<<");
if (err != ERR_NONE)
return err;
......
......@@ -165,7 +165,7 @@ sigil_err_t read_xref_table(sigil_t *sgl)
return ERR_ALLOCATION;
}
if ((err = parse_word(sgl, "xref")) != ERR_NONE)
if ((err = skip_word(sgl, "xref")) != ERR_NONE)
return err;
while (!xref_end) { // for all xref sections
......@@ -192,9 +192,9 @@ sigil_err_t read_xref_table(sigil_t *sgl)
if (err != ERR_NONE)
return err;
if (parse_word(sgl, "f") == ERR_NONE)
if (skip_word(sgl, "f") == ERR_NONE)
continue;
err = parse_word(sgl, "n");
err = skip_word(sgl, "n");
if (err != ERR_NONE)
return err;
......@@ -316,7 +316,7 @@ int sigil_xref_self_test(int verbosity)
"startxref\n" \
"1234567890\n"\
"\045\045EOF"; // %%EOF
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 (read_startxref(sgl) != ERR_NONE ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment