Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,38 +261,42 @@ int wolfSSL_TXT_DB_create_index(WOLFSSL_TXT_DB *db, int field,
{
WOLFSSL_ENTER("wolfSSL_TXT_DB_create_index");
(void)qual;
(void)cmp;

if (!db || !hash || !cmp || field >= db->num_fields || field < 0) {
WOLFSSL_MSG("Bad parameter");
return WOLFSSL_FAILURE;
}

db->hash_fn[field] = hash;
db->cmp_fn[field] = cmp;

return WOLFSSL_SUCCESS;
}

WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx,
WOLFSSL_STRING *value)
{
WOLF_STACK_OF(WOLFSSL_STRING)* data;
WOLFSSL_STRING* row = NULL;
unsigned long hash;

WOLFSSL_ENTER("wolfSSL_TXT_DB_get_by_index");

if (!db || !db->data || idx < 0 || idx >= db->num_fields) {
if (!db || !db->data || !value || idx < 0 || idx >= db->num_fields) {
WOLFSSL_MSG("Bad parameter");
return NULL;
}

if (!db->hash_fn[idx]) {
WOLFSSL_MSG("Missing hash functions");
if (!db->hash_fn[idx] || !db->cmp_fn[idx]) {
WOLFSSL_MSG("Missing hash or compare functions");
return NULL;
}

/* If first data struct has correct hash function
* then assume others do too */
if (db->data->hash_fn != db->hash_fn[idx]) {
/* Set the hash and comp functions */
WOLF_STACK_OF(WOLFSSL_STRING)* data = db->data;
data = db->data;
while (data) {
if (data->hash_fn != db->hash_fn[idx]) {
data->hash_fn = db->hash_fn[idx];
Expand All @@ -301,7 +305,22 @@ WOLFSSL_STRING *wolfSSL_TXT_DB_get_by_index(WOLFSSL_TXT_DB *db, int idx,
data= data->next;
}
}
return (WOLFSSL_STRING*) wolfSSL_lh_retrieve(db->data, value);

hash = db->hash_fn[idx](value);
for (data = db->data; data != NULL; data = data->next) {
row = (WOLFSSL_STRING*)wolfssl_sk_node_get_data(data, 0);
if (row != NULL) {
if (data->hash == 0) {
data->hash = db->hash_fn[idx](row);
}
if ((data->hash == hash) && (db->cmp_fn[idx](row, value) == 0)) {
break;
}
}
row = NULL;
}

return row;
}

#endif /* OPENSSL_ALL && !NO_BIO */
Expand Down
20 changes: 20 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -26658,6 +26658,13 @@ static int TXT_DB_cmp(const WOLFSSL_STRING *a, const WOLFSSL_STRING *b)
{
return XSTRCMP(a[3], b[3]);
}

/* Every row collides, so only TXT_DB_cmp can tell rows apart */
static word32 TXT_DB_hash_const(const WOLFSSL_STRING *s)
{
(void)s;
return 1;
}
#endif

static int test_wolfSSL_TXT_DB(void)
Expand All @@ -26666,6 +26673,7 @@ static int test_wolfSSL_TXT_DB(void)
#if !defined(NO_FILESYSTEM) && !defined(NO_BIO)
BIO *bio = NULL;
TXT_DB *db = NULL;
WOLFSSL_STRING *row = NULL;
const int columns = 6;
const char *fields[6] = {
"V",
Expand Down Expand Up @@ -26710,6 +26718,18 @@ static int test_wolfSSL_TXT_DB(void)
fields[3] = "";
ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));

/* Colliding hashes: the row returned must be the one cmp matches */
ExpectIntEQ(TXT_DB_create_index(db, 3, NULL,
(wolf_sk_hash_cb)(wc_ptr_t)TXT_DB_hash_const,
(wolf_lh_compare_cb)TXT_DB_cmp), 1);
fields[3] = "12DA";
ExpectNotNull(row = TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));
if (row != NULL) {
ExpectStrEQ(row[3], "12DA");
}
fields[3] = "FFFF";
ExpectNull(TXT_DB_get_by_index(db, 3, (WOLFSSL_STRING*)fields));

TXT_DB_free(db);
#endif
return EXPECT_RESULT();
Expand Down
6 changes: 4 additions & 2 deletions wolfssl/openssl/txt_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@

#define WOLFSSL_TXT_DB_MAX_FIELDS 10

typedef int (*wolf_lh_compare_cb)(const void* a,
const void* b);

struct WOLFSSL_TXT_DB {
int num_fields;
WOLF_STACK_OF(WOLFSSL_STRING) *data;
long error;
long arg1;
long arg2;
wolf_sk_hash_cb hash_fn[WOLFSSL_TXT_DB_MAX_FIELDS];
wolf_lh_compare_cb cmp_fn[WOLFSSL_TXT_DB_MAX_FIELDS];
};

typedef struct WOLFSSL_TXT_DB WOLFSSL_TXT_DB;
typedef int (*wolf_lh_compare_cb)(const void* a,
const void* b);

WOLFSSL_API WOLFSSL_TXT_DB *wolfSSL_TXT_DB_read(WOLFSSL_BIO *in, int num);
WOLFSSL_API long wolfSSL_TXT_DB_write(WOLFSSL_BIO *out, WOLFSSL_TXT_DB *db);
Expand Down
Loading