Skip to content
Snippets Groups Projects
Commit 47407f2d authored by Jonathan Schöbel's avatar Jonathan Schöbel
Browse files

look for duplicate tags in Validator

When a tag is made known to the Validator, which it already knows, the
old id is returned and nothing is added.
As this has to be checked by iterating over all known tags, a new helper
function is written for both SH_Validator_check_tag and
SH_Validator_register_tag: SH_Validator_get_tag.

Because we want also to test this function, we have to include
validator.c in the test file and override the static keyword by an empty
macro. It isn't possible any more to check for correct overflowdetection
by setting the index to UINT_MAX, because it will be iterated over all
data, thus raising an SIGSEGV when doing so. This is solved by filling
garbage unil UINT_MAX is really reached. As there would be an timeout
and it would fill RAM with around 40 GB of garbage, UINT_MAX is
overriden prior to inclusion of validator.c .
parent 9cf67805
Branches
Tags
No related merge requests found
......@@ -20,6 +20,7 @@ PKG_CHECK_MODULES([CHECK], [check >= 0.9.4])
# Checks for header files.
AC_CHECK_HEADER([errno.h])
AC_CHECK_HEADER([limits.h])
AC_CHECK_HEADER([math.h])
AC_CHECK_HEADER([stdbool.h])
AC_CHECK_HEADER([stdio.h])
AC_CHECK_HEADER([stdlib.h])
......
......@@ -105,10 +105,50 @@ free_tags (struct SH_Validator * validator)
return;
}
static inline tag_t
SH_Validator_get_tag (struct SH_Validator * validator, const char * tag)
{
unsigned int index;
for (index = 0; index < validator->tag_n; index++)
{
if (strcmp (validator->tags[index].name, tag) == 0)
{
return validator->tags[index].id;
}
}
return TAG_ERR;
}
bool
SH_Validator_check_tag (struct SH_Validator * validator,
const char * tag)
{
if (SH_Validator_get_tag (validator, tag) == TAG_ERR)
{
return FALSE;
}
else
{
return TRUE;
}
}
tag_t
SH_Validator_register_tag (struct SH_Validator * validator,
const char * tag, struct SH_Error * error)
{
tag_t tag_id;
/* tag already registered */
tag_id = SH_Validator_get_tag (validator, tag);
if (tag_id != TAG_ERR)
{
return tag_id;
}
/* abort on overflow */
if (validator->tag_n == UINT_MAX
|| validator->last_tag == TAG_MAX)
......@@ -164,20 +204,3 @@ SH_Validator_register_tag (struct SH_Validator * validator,
return validator->last_tag;
}
bool
SH_Validator_check_tag (struct SH_Validator * validator,
const char * tag)
{
unsigned int index;
for (index = 0; index < validator->tag_n; index++)
{
if (strcmp (validator->tags[index].name, tag) == 0)
{
return TRUE;
}
}
return FALSE;
}
......@@ -37,5 +37,4 @@ sefht_fragment_test_LDADD += $(LDADD)
sefht_validator_test_SOURCES = test_validator.c
sefht_validator_test_LDADD =
sefht_validator_test_LDADD += $(top_builddir)/src/validator.o
sefht_validator_test_LDADD += $(LDADD)
......@@ -23,12 +23,23 @@
#include <check.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
/* test static method */
#define static
/* lower UINT_MAX as we try to reach it */
#include <limits.h>
#define UINT_MAX 20
#include "macro.h"
#include "error.h"
#include "validator.h"
/* C file is needed, because we wan't to override UINT_MAX and static */
#include "validator.c"
START_TEST(test_validator)
......@@ -60,7 +71,9 @@ START_TEST(test_validator_tag)
const char * tag4 = "link";
const char * tag5 = "main";
const char * tag6 = "article";
char * tagN;
tag_t tag;
tag_t tag_return;
bool check;
validator = SH_Validator_new (NULL);
......@@ -75,14 +88,47 @@ START_TEST(test_validator_tag)
ck_assert_int_eq (validator->tags[0].id, tag);
ck_assert_str_eq (validator->tags[0].name, tag1);
tag_return = SH_Validator_get_tag (validator, tag1);
ck_assert_int_eq (tag_return, tag);
/* retry without error */
tag_return = SH_Validator_register_tag (validator, tag1, NULL);
ck_assert_int_eq (tag_return, tag);
ck_assert_int_eq (validator->tag_n, 1);
ck_assert_int_eq (validator->last_tag, tag);
ck_assert_int_eq (validator->tags[0].id, tag);
ck_assert_str_eq (validator->tags[0].name, tag1);
/* fail without error */
validator->tag_n = UINT_MAX;
/* make method fail by filling with garbage until
* upper boundary is reached */
/* ensure enough space inside string*/
/* log10 +1 = number length */
/* +3 "tag" */
/* +1 NULL */
/* = +5 */
tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
sizeof (char));
/* fill with garbage */
while (validator->tag_n != UINT_MAX)
{
printf ("tag%d\n", validator->tag_n);
sprintf (tagN, "tag%d", validator->tag_n);
SH_Validator_register_tag (validator, tagN, NULL);
}
tag = SH_Validator_register_tag (validator, tag2, NULL);
ck_assert_int_eq (tag, TAG_ERR);
ck_assert_int_eq (validator->tag_n, UINT_MAX);
ck_assert_int_eq (validator->last_tag, 1);
ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);
tag_return = SH_Validator_get_tag (validator, tag2);
ck_assert_int_eq (tag_return, TAG_ERR);
/* fail2 without error */
validator->tag_n = 1;
......@@ -94,6 +140,9 @@ START_TEST(test_validator_tag)
ck_assert_int_eq (validator->tag_n, 1);
ck_assert_int_eq (validator->last_tag, TAG_MAX);
tag_return = SH_Validator_get_tag (validator, tag3);
ck_assert_int_eq (tag_return, TAG_ERR);
/* success with error */
validator->last_tag = 1;
tag = SH_Validator_register_tag (validator, tag4, &error);
......@@ -106,15 +155,38 @@ START_TEST(test_validator_tag)
ck_assert_int_eq (validator->tags[1].id, tag);
ck_assert_str_eq (validator->tags[1].name, tag4);
tag_return = SH_Validator_get_tag (validator, tag4);
ck_assert_int_eq (tag_return, tag);
/* fail with error */
validator->tag_n = UINT_MAX;
/* make method fail by filling with garbage until
* upper boundary is reached */
/* ensure enough space inside string*/
/* log10 +1 = number length */
/* +3 "tag" */
/* +1 NULL */
/* = +5 */
tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
sizeof (char));
/* fill with garbage */
while (validator->tag_n != UINT_MAX)
{
printf ("tag%d\n", validator->tag_n);
sprintf (tagN, "tag%d", validator->tag_n);
SH_Validator_register_tag (validator, tagN, NULL);
}
tag = SH_Validator_register_tag (validator, tag5, &error);
ck_assert_int_eq (tag, TAG_ERR);
ck_assert_int_eq (error.type, DOMAIN_ERROR);
ck_assert_int_eq (validator->tag_n, UINT_MAX);
ck_assert_int_eq (validator->last_tag, 2);
ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);
tag_return = SH_Validator_get_tag (validator, tag5);
ck_assert_int_eq (tag_return, TAG_ERR);
/* fail2 with error */
validator->tag_n = 2;
......@@ -127,6 +199,9 @@ START_TEST(test_validator_tag)
ck_assert_int_eq (validator->tag_n, 2);
ck_assert_int_eq (validator->last_tag, TAG_MAX);
tag_return = SH_Validator_get_tag (validator, tag6);
ck_assert_int_eq (tag_return, TAG_ERR);
/* check tag */
check = SH_Validator_check_tag (validator, tag1);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment