merged in parent

ENGINE-641
commit 2244761932

@ -1155,7 +1155,7 @@
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
SDKROOT = iphoneos;
VALID_ARCHS = "arm64 armv7s armv7";
VALID_ARCHS = "$(VALID_ARCHS) x86_64";
};
name = Debug;
};
@ -1214,7 +1214,7 @@
OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
VALID_ARCHS = "arm64 armv7s armv7";
VALID_ARCHS = "$(VALID_ARCHS) x86_64";
};
name = Release;
};

@ -108,6 +108,23 @@ DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identit
return list_curr->next;
}
// returns *head* of list
DYNAMIC_API identity_list* identity_list_join(identity_list *first_list, identity_list *second_list) {
if (!first_list) {
if (!second_list)
return NULL;
return second_list;
}
if (second_list) {
identity_list* list_curr = first_list;
while (list_curr->next)
list_curr = list_curr->next;
list_curr->next = second_list;
}
return first_list;
}
DYNAMIC_API int identity_list_length(const identity_list *id_list)
{
int len = 0;

@ -63,6 +63,16 @@ DYNAMIC_API void free_identity_list(identity_list *id_list);
DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident);
// identity_list_add - join second identity_list to the first.
//
// parameters:
// first_list (in) identity_list to add to
// second_list (in) identity list to add
//
// return value:
// pointer to the HEAD of the new list, or NULL if both lists are empty.
//
DYNAMIC_API identity_list *identity_list_join(identity_list *first_list, identity_list* second_list);
// identity_list_length() - get length of identity_list
//
@ -73,9 +83,7 @@ DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identit
// length of identity_list in number of elements
DYNAMIC_API int identity_list_length(const identity_list *id_list);
#ifdef __cplusplus
}
#endif

@ -474,6 +474,8 @@ static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
PEP_STATUS status;
bool is_identity_default, is_user_default, is_address_default;
bool no_stored_default = EMPTYSTR(stored_ident->fpr);
status = get_valid_pubkey(session, stored_ident,
&is_identity_default,
&is_user_default,
@ -492,7 +494,12 @@ static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
stored_ident->comm_type = ct;
}
}
else {
else if (status != PEP_STATUS_OK) {
free(stored_ident->fpr);
stored_ident->fpr = NULL;
stored_ident->comm_type = PEP_ct_key_not_found;
}
else { // no key returned, but status ok?
if (stored_ident->comm_type == PEP_ct_unknown)
stored_ident->comm_type = PEP_ct_key_not_found;
}
@ -543,8 +550,17 @@ static PEP_STATUS prepare_updated_identity(PEP_SESSION session,
// or identity AND is valid for this address, set in DB
// as default
status = set_identity(session, return_id);
}
else if (no_stored_default && !EMPTYSTR(return_id->fpr)
&& return_id->comm_type != PEP_ct_key_revoked
&& return_id->comm_type != PEP_ct_key_expired
&& return_id->comm_type != PEP_ct_key_expired_but_confirmed
&& return_id->comm_type != PEP_ct_mistrusted
&& return_id->comm_type != PEP_ct_key_b0rken) {
// We would have stored this anyway for a first-time elected key. We just have an ident w/ no default already.
status = set_identity(session, return_id);
}
else {
else { // this is a key other than the default, but there IS a default (FIXME: fdik, do we really want behaviour below?)
// Store without default fpr/ct, but return the fpr and ct
// for current use
char* save_fpr = return_id->fpr;

@ -3145,7 +3145,6 @@ static PEP_STATUS reconcile_identity_lists(identity_list* src_ids,
}
static PEP_STATUS reconcile_sent_and_recv_info(message* src, message* inner_message) {
PEP_STATUS status = PEP_STATUS_OK;
if (!src || !inner_message)
return PEP_ILLEGAL_VALUE;

@ -60,6 +60,7 @@ typedef enum {
PEP_KEY_IMPORTED = 0x0220,
PEP_NO_KEY_IMPORTED = 0x0221,
PEP_KEY_IMPORT_STATUS_UNKNOWN = 0x0222,
PEP_SOME_KEYS_IMPORTED = 0x0223,
PEP_CANNOT_FIND_IDENTITY = 0x0301,
PEP_CANNOT_SET_PERSON = 0x0381,

@ -1447,6 +1447,33 @@ PEP_STATUS pgp_verify_text(
if (size == 0 || sig_size == 0)
return PEP_DECRYPT_WRONG_FORMAT;
#if TRACING > 0
{
int cr = 0;
int crlf = 0;
int lf = 0;
for (int i = 0; i < size; i ++) {
// CR
if (text[i] == '\r') {
cr ++;
}
// LF
if (text[i] == '\n') {
if (i > 0 && text[i - 1] == '\r') {
cr --;
crlf ++;
} else {
lf ++;
}
}
}
T("Text to verify: %zd bytes with %d crlfs, %d bare crs and %d bare lfs",
size, crlf, cr, lf);
}
#endif
cookie.recipient_keylist = new_stringlist(NULL);
if (!cookie.recipient_keylist)
ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
@ -1854,7 +1881,27 @@ PEP_STATUS pgp_delete_keypair(PEP_SESSION session, const char *fpr_raw)
return status;
}
PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
static unsigned int count_keydata_parts(const char* key_data, size_t size) {
unsigned int retval = 0;
const char* pgp_begin = "-----BEGIN PGP";
size_t prefix_len = strlen(pgp_begin);
size_t size_remaining = size;
while (key_data) {
if (size_remaining <= prefix_len || key_data[0] == '\0')
break;
key_data = strnstr(key_data, pgp_begin, size_remaining);
if (key_data) {
retval++;
key_data += prefix_len;
size_remaining -= prefix_len;
}
}
return retval;
}
PEP_STATUS _pgp_import_keydata(PEP_SESSION session, const char *key_data,
size_t size, identity_list **private_idents)
{
PEP_STATUS status = PEP_NO_KEY_IMPORTED;
@ -1986,6 +2033,78 @@ PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
return status;
}
PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
size_t size, identity_list **private_idents)
{
unsigned int keycount = count_keydata_parts(key_data, size);
if (keycount < 2)
return(_pgp_import_keydata(session, key_data, size, private_idents));
const char* pgp_begin = "-----BEGIN PGP";
size_t prefix_len = strlen(pgp_begin);
unsigned int i;
const char* curr_begin;
size_t curr_size;
identity_list* collected_idents = NULL;
PEP_STATUS retval = PEP_KEY_IMPORTED;
for (i = 0, curr_begin = key_data; i < keycount; i++) {
const char* next_begin = NULL;
// This is assured to be OK because the count function above
// made sure that THIS round contains at least prefix_len chars
// We used strnstr to count, so we know that strstr will be ok.
if (strlen(curr_begin + prefix_len) > prefix_len)
next_begin = strstr(curr_begin + prefix_len, pgp_begin);
if (next_begin)
curr_size = next_begin - curr_begin;
else
curr_size = (key_data + size) - curr_begin;
PEP_STATUS curr_status = _pgp_import_keydata(session, curr_begin, curr_size, private_idents);
if (private_idents && *private_idents) {
if (!collected_idents)
collected_idents = *private_idents;
else
identity_list_join(collected_idents, *private_idents);
*private_idents = NULL;
}
if (curr_status != retval) {
switch (curr_status) {
case PEP_NO_KEY_IMPORTED:
case PEP_KEY_NOT_FOUND:
case PEP_UNKNOWN_ERROR:
switch (retval) {
case PEP_KEY_IMPORTED:
retval = PEP_SOME_KEYS_IMPORTED;
break;
case PEP_UNKNOWN_ERROR:
retval = curr_status;
break;
default:
break;
}
break;
case PEP_KEY_IMPORTED:
retval = PEP_SOME_KEYS_IMPORTED;
default:
break;
}
}
curr_begin = next_begin;
}
if (private_idents)
*private_idents = collected_idents;
return retval;
}
PEP_STATUS pgp_export_keydata(
PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
bool secret)
@ -2498,6 +2617,22 @@ PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
// Is the TPK live?
*expired = !pgp_tpk_alive_at(tpk, when);
#ifdef TRACING
{
char buffer[26];
time_t now = time(NULL);
if (when == now || when == now - 1) {
sprintf(buffer, "now");
} else {
struct tm tm;
gmtime_r(&when, &tm);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
}
T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
}
#endif
if (*expired)
goto out;
@ -2528,9 +2663,15 @@ PEP_STATUS pgp_key_expired(PEP_SESSION session, const char *fpr,
*expired = !(can_encrypt && can_sign && can_certify);
T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
can_encrypt ? "" : "not",
can_sign ? "" : "not",
can_certify ? "" : "not",
*expired ? "" : "not ");
out:
pgp_tpk_free(tpk);
T("(%s) -> %s", fpr, pEp_status_to_string(status));
T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
return status;
}

@ -198,6 +198,43 @@ size_t strlcat(char* dst, const char* src, size_t size) {
return retval;
}
char *strnstr(const char *big, const char *little, size_t len) {
if (big == NULL || little == NULL)
return NULL;
if (*little == '\0')
return (char*)big;
const char* curr_big = big;
size_t little_len = strlen(little);
size_t remaining = len;
const char* retval = NULL;
for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
// find first-char match
if (*curr_big != *little) {
continue;
}
retval = curr_big;
const char* inner_big = retval + 1;
const char* curr_little = little + 1;
int j;
for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
if (*inner_big != *curr_little) {
retval = NULL;
break;
}
}
if (retval)
break;
}
return (char*)retval;
}
#ifdef USE_NETPGP
// FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
int regnexec(const regex_t* preg, const char* string,
@ -449,4 +486,3 @@ const char *gpg_agent_conf(int reset)
return NULL;
}
#endif

@ -67,6 +67,7 @@ extern char* SystemDB;
#if !defined(BSD) && !defined(__APPLE__)
size_t strlcpy(char* dst, const char* src, size_t size);
size_t strlcat(char* dst, const char* src, size_t size);
char *strnstr(const char *big, const char *little, size_t len);
// N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
// the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is

@ -283,6 +283,41 @@ size_t strlcat(char* dst, const char* src, size_t size) {
dst[start_len + size_to_copy] = '\0';
return retval;
}
char *strnstr(const char *big, const char *little, size_t len) {
if (big == NULL || little == NULL)
return NULL;
if (*little == '\0')
return (char*)big;
const char* curr_big = big;
size_t little_len = strlen(little);
size_t remaining = len;
const char* retval = NULL;
for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
// find first-char match
if (*curr_big != *little) {
continue;
}
retval = curr_big;
const char* inner_big = retval + 1;
const char* curr_little = little + 1;
int j;
for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
if (*inner_big != *curr_little) {
retval = NULL;
break;
}
}
if (retval)
break;
}
return (char*)retval;
}
int mkstemp(char *templ)
{

@ -74,6 +74,8 @@ char *stpcpy(char *dst, const char *src);
size_t strlcpy(char* dst, const char* src, size_t size);
size_t strlcat(char* dst, const char* src, size_t size);
char *strnstr(const char *big, const char *little, size_t len);
const char *windoze_local_db(void);
const char *windoze_system_db(void);

@ -35,6 +35,7 @@ static inline const char *pEp_status_to_string(PEP_STATUS status) {
case PEP_KEY_IMPORTED: return "PEP_KEY_IMPORTED";
case PEP_NO_KEY_IMPORTED: return "PEP_NO_KEY_IMPORTED";
case PEP_KEY_IMPORT_STATUS_UNKNOWN: return "PEP_KEY_IMPORT_STATUS_UNKNOWN";
case PEP_SOME_KEYS_IMPORTED: return "PEP_SOME_KEYS_IMPORTED";
case PEP_CANNOT_FIND_IDENTITY: return "PEP_CANNOT_FIND_IDENTITY";
case PEP_CANNOT_SET_PERSON: return "PEP_CANNOT_SET_PERSON";

@ -0,0 +1,35 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifndef STRNSTR_H
#define STRNSTR_H
#include <string>
#include "EngineTestIndividualSuite.h"
using namespace std;
class StrnstrTests : public EngineTestIndividualSuite {
public:
StrnstrTests(string test_suite, string test_home_dir);
private:
void check_strnstr_equal();
void check_strnstr_first_null();
void check_strnstr_second_null();
void check_strnstr_both_null();
void check_strnstr_first_empty();
void check_strnstr_second_empty();
void check_strnstr_both_empty();
void check_strnstr_first_letter_only();
void check_strnstr_first_two_only();
void check_strnstr_all_but_last();
void check_strnstr_same_len_all_but_last();
void check_strnstr_same_len_none();
void check_strnstr_same_big_smaller();
void check_strnstr_shift_one_no_match();
void check_strnstr_shift_to_end();
void check_strnstr_match_after_end();
void check_strnstr_equal_but_size_too_small();
};
#endif

@ -71,6 +71,7 @@
#include "KeyAttachmentTests.h"
#include "OwnKeysRetrieveTests.h"
#include "TrustManipulationTests.h"
#include "StrnstrTests.h"
#include "SyncTests.h"
#include "SenderFPRTests.h"
#include "RevocationTests.h"
@ -137,6 +138,7 @@ const char* SuiteMaker::all_suites[] = {
"KeyAttachmentTests",
"OwnKeysRetrieveTests",
"TrustManipulationTests",
"StrnstrTests",
"SyncTests",
"SenderFPRTests",
"RevocationTests",
@ -265,6 +267,8 @@ void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_
*test_suite = new OwnKeysRetrieveTests(test_class_name, test_home);
else if (strcmp(test_class_name, "TrustManipulationTests") == 0)
*test_suite = new TrustManipulationTests(test_class_name, test_home);
else if (strcmp(test_class_name, "StrnstrTests") == 0)
*test_suite = new StrnstrTests(test_class_name, test_home);
else if (strcmp(test_class_name, "SyncTests") == 0)
*test_suite = new SyncTests(test_class_name, test_home);
else if (strcmp(test_class_name, "SenderFPRTests") == 0)

@ -108,6 +108,13 @@ void CheckRenewedExpiredKeyTrustStatusTests::check_renewed_expired_key_trust_sta
status = update_identity(session, expired_inquisitor);
TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
PEP_comm_type ct = expired_inquisitor->comm_type;
TEST_ASSERT_MSG(ct == PEP_ct_key_not_found, tl_ct_string(ct));
TEST_ASSERT(!expired_inquisitor->fpr);
expired_inquisitor->fpr = strdup(inquisitor_fpr);
status = get_trust(session, expired_inquisitor);
ct = expired_inquisitor->comm_type;
TEST_ASSERT(status == PEP_STATUS_OK);
TEST_ASSERT_MSG(ct == PEP_ct_key_expired_but_confirmed, tl_ct_string(ct));
// Ok, so I want to make sure we make an entry, so I'll try to decrypt the message WITH
@ -250,6 +257,13 @@ void CheckRenewedExpiredKeyTrustStatusTests::check_renewed_expired_key_trust_sta
status = update_identity(session, expired_inquisitor);
TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
PEP_comm_type ct = expired_inquisitor->comm_type;
TEST_ASSERT_MSG(ct == PEP_ct_key_not_found, tl_ct_string(ct));
TEST_ASSERT(!expired_inquisitor->fpr);
expired_inquisitor->fpr = strdup(inquisitor_fpr);
status = get_trust(session, expired_inquisitor);
ct = expired_inquisitor->comm_type;
TEST_ASSERT(status == PEP_STATUS_OK);
TEST_ASSERT_MSG(ct == PEP_ct_key_expired_but_confirmed, tl_ct_string(ct));
// Ok, so I want to make sure we make an entry, so I'll try to decrypt the message WITH

@ -255,8 +255,9 @@ void ExternalRevokeTests::check_external_revoke() {
status = get_trust(session, recip1);
cout << "Recip's trust DB comm_type (should be unknown, as we're using a keyring-only key, not in DB) = " << tl_ct_string(recip1->comm_type) << endl;
TEST_ASSERT_MSG((recip1->comm_type != PEP_ct_OpenPGP_unconfirmed), "recip1->comm_type != PEP_ct_OpenPGP_unconfirmed");
// cout << "Recip's trust DB comm_type (should be unknown, as we're using a keyring-only key, not in DB) = " << tl_ct_string(recip1->comm_type) << endl;
cout << "Recip's trust DB comm_type (should PEP_ct_OpenPGP_unconfirmed), as we now record this when using update_identity on no-default idents = " << tl_ct_string(recip1->comm_type) << endl;
TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_OpenPGP_unconfirmed), tl_ct_string(recip1->comm_type));
// decrypt message
// free_message(outgoing_msg);
@ -285,8 +286,9 @@ void ExternalRevokeTests::check_external_revoke() {
status = get_trust(session, recip1);
cout << "Recip's trust DB comm_type (should be unknown - there's nothing in the DB) = " << tl_ct_string(recip1->comm_type) << endl;
TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_unknown), "recip1->comm_type == PEP_ct_unknown");
// cout << "Recip's trust DB comm_type (should be unknown - there's nothing in the DB) = " << tl_ct_string(recip1->comm_type) << endl;
cout << "Recip's trust DB comm_type (should be PEP_ct_OpenPGP_unconfirmed, as we now store it.) = " << tl_ct_string(recip1->comm_type) << endl;
TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_OpenPGP_unconfirmed), tl_ct_string(recip1->comm_type));
free_message(encrypted_outgoing_msg);
free_message(decrypted_msg);

@ -48,12 +48,23 @@ void IOS1664Tests::check_i_o_s1664() {
pEp_identity* you = new_identity("superxat@gmail.com", NULL, NULL, NULL);
// N.B. while obviously it would be better to write the test expecting us to
// accept the key, I'm actually testing that we don't get the wrong status
// based on the presumption of rejection
message* out_msg = new_message(PEP_dir_outgoing);
out_msg->from = me;
out_msg->to = new_identity_list(you);
out_msg->shortmsg = strdup("Hussidente 2020!");
out_msg->longmsg = strdup("A Huss in every office!");
status = identity_rating(session, out_msg->from, &rating);
TEST_ASSERT(status == PEP_STATUS_OK);
TEST_ASSERT_MSG(rating == PEP_rating_trusted_and_anonymized, tl_rating_string(rating));
status = identity_rating(session, out_msg->to->ident, &rating);
TEST_ASSERT_MSG(status == PEP_KEY_NOT_FOUND, tl_status_string(status));
TEST_ASSERT_MSG(rating == PEP_rating_undefined, tl_rating_string(rating));
status = outgoing_message_rating(session, out_msg, &rating);
TEST_ASSERT(rating == PEP_rating_unencrypted);

@ -500,10 +500,10 @@ void NewUpdateIdAndMyselfTests::key_elect_expired_key() {
TEST_ASSERT_MSG((bernd->user_id), "bernd->user_id");
TEST_ASSERT_MSG((strcmp(bernd->user_id, bernd_userid) == 0), "strcmp(bernd->user_id, bernd_userid) == 0"); // ???
TEST_ASSERT_MSG((!bernd->me), "!bernd->me");
TEST_ASSERT_MSG((bernd->comm_type == PEP_ct_key_expired), "bernd->comm_type == PEP_ct_key_expired");
TEST_ASSERT_MSG((bernd->comm_type == PEP_ct_key_not_found), tl_ct_string(bernd->comm_type));
TEST_ASSERT_MSG((strcmp(bernd->address, bernd_address) == 0), "strcmp(bernd->address, bernd_address) == 0");
cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_expired" << endl << endl;
cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_not_found" << endl << endl;
free_identity(bernd);
}

@ -52,8 +52,24 @@ void RevocationTests::revocation() {
TEST_ASSERT_MSG((status == PEP_TEST_KEY_IMPORT_SUCCESS), "status == PEP_STATUS_OK");
pEp_identity* post = new_identity("linda@example.org", NULL, NULL, NULL);
// string save_fpr = post->fpr;
stringlist_t* keylist = NULL;
status = find_keys(session, "linda@example.org", &keylist);
TEST_ASSERT(status == PEP_STATUS_OK);
status = update_identity(session, post);
// PEP_KEY_UNSUITABLE => revoked (or something similar).
TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
TEST_ASSERT_MSG((post->comm_type == PEP_ct_key_not_found), tl_ct_string(post->comm_type));
free(post->fpr);
post->fpr = strdup(keylist->value);
status = get_trust(session, post);
TEST_ASSERT(status == PEP_STATUS_OK);
TEST_ASSERT_MSG((post->comm_type == PEP_ct_key_revoked), tl_ct_string(post->comm_type));
free_identity(pre);
free_identity(post);
free_stringlist(keylist);
}

@ -0,0 +1,154 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#include <stdlib.h>
#include <cstring>
#include <string>
#include <cpptest.h>
#include "test_util.h"
#include "pEpEngine.h"
#include "platform_unix.h"
#include "EngineTestIndividualSuite.h"
#include "StrnstrTests.h"
using namespace std;
StrnstrTests::StrnstrTests(string suitename, string test_home_dir) :
EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal"),
static_cast<Func>(&StrnstrTests::check_strnstr_equal)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_second_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_second_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_both_empty"),
static_cast<Func>(&StrnstrTests::check_strnstr_both_empty)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_letter_only"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_letter_only)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_two_only"),
static_cast<Func>(&StrnstrTests::check_strnstr_first_two_only)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_all_but_last"),
static_cast<Func>(&StrnstrTests::check_strnstr_all_but_last)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_all_but_last"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_len_all_but_last)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_none"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_len_none)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_big_smaller"),
static_cast<Func>(&StrnstrTests::check_strnstr_same_big_smaller)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_one_no_match"),
static_cast<Func>(&StrnstrTests::check_strnstr_shift_one_no_match)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_to_end"),
static_cast<Func>(&StrnstrTests::check_strnstr_shift_to_end)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_match_after_end"),
static_cast<Func>(&StrnstrTests::check_strnstr_match_after_end)));
add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal_but_size_too_small"),
static_cast<Func>(&StrnstrTests::check_strnstr_equal_but_size_too_small)));
}
void StrnstrTests::check_strnstr_equal() {
const char* big = "Bob123";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
}
void StrnstrTests::check_strnstr_first_empty() {
const char* big = "";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_second_empty() {
const char* big = "YerMama";
const char* little = "";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_both_empty() {
const char* big = "";
const char* little = "";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_first_letter_only() {
const char* big = "Bob123";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_first_two_only() {
const char* big = "Bob123";
const char* little = "Boof";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_all_but_last() {
const char* big = "BeesBeesBees";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_len_all_but_last() {
const char* big = "Bees";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_len_none() {
const char* big = "1234";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_same_big_smaller() {
const char* big = "Bee";
const char* little = "Bees";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_shift_one_no_match() {
const char* big = "1Bee";
const char* little = "Bees";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_shift_to_end() {
const char* big = "BigBeeWithExtraBeef";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size);
TEST_ASSERT_MSG(result == big + 15, result);
TEST_ASSERT(true);
}
void StrnstrTests::check_strnstr_match_after_end() {
const char* big = "EatMoreBeef";
const char* little = "Beef";
size_t size = strlen(big);
const char* result = strnstr(big, little, size - 1);
TEST_ASSERT_MSG(result == NULL, result);
}
void StrnstrTests::check_strnstr_equal_but_size_too_small() {
const char* big = "Bob123";
const char* little = "Bob123";
size_t size = strlen(big);
const char* result = strnstr(big, little, size - 1);
TEST_ASSERT_MSG(result == NULL, result);
}
Loading…
Cancel
Save