merge sync IOS-1576
authorbuff <andreas@pep-project.org>
Mon, 08 Jul 2019 16:44:35 +0200
branchIOS-1576
changeset 3928117be5371dd4
parent 3897 688eb9375ece
parent 3905 1d3c2c487980
child 3929 408594db81f1
merge sync
     1.1 --- a/src/message_api.c	Thu Jul 04 10:52:32 2019 +0200
     1.2 +++ b/src/message_api.c	Mon Jul 08 16:44:35 2019 +0200
     1.3 @@ -3126,7 +3126,6 @@
     1.4  }
     1.5  
     1.6  static PEP_STATUS reconcile_sent_and_recv_info(message* src, message* inner_message) {
     1.7 -    PEP_STATUS status = PEP_STATUS_OK;
     1.8      if (!src || !inner_message)
     1.9          return PEP_ILLEGAL_VALUE;
    1.10          
     2.1 --- a/src/pEpEngine.c	Thu Jul 04 10:52:32 2019 +0200
     2.2 +++ b/src/pEpEngine.c	Mon Jul 08 16:44:35 2019 +0200
     2.3 @@ -4247,8 +4247,27 @@
     2.4      if (!(session && pattern && keylist))
     2.5          return PEP_ILLEGAL_VALUE;
     2.6  
     2.7 -    return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
     2.8 -            keylist);
     2.9 +    PEP_STATUS status = session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
    2.10 +                                                                         keylist);
    2.11 +                                                                         
    2.12 +#ifndef USE_GPG
    2.13 +    if (*keylist == NULL) {
    2.14 +        // we have a problem, in that older GPG keys with no username associated don't 
    2.15 +        // quote out the address-as-username, meaning the uid is non-standard.
    2.16 +        // sequoia then stores the whole uid string for lookup, so we try again here with 
    2.17 +        // a whole-uid-pattern:
    2.18 +        if (strchr(pattern, '@')) {
    2.19 +            char* new_pattern = calloc(2*strlen(pattern) + 4, 1);
    2.20 +            int n = sprintf(new_pattern, "%s <%s>", pattern, pattern);
    2.21 +            if (n > 0)
    2.22 +                status = session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, new_pattern,
    2.23 +                                                                          keylist);
    2.24 +            free(new_pattern);                                                                      
    2.25 +        }    
    2.26 +    }
    2.27 +#endif 
    2.28 +    
    2.29 +    return status;
    2.30  }
    2.31  
    2.32  
     3.1 --- a/src/pgp_sequoia.c	Thu Jul 04 10:52:32 2019 +0200
     3.2 +++ b/src/pgp_sequoia.c	Mon Jul 08 16:44:35 2019 +0200
     3.3 @@ -1854,16 +1854,21 @@
     3.4      return status;
     3.5  }
     3.6  
     3.7 -static unsigned int count_keydata_parts(const char* key_data) {
     3.8 +static unsigned int count_keydata_parts(const char* key_data, size_t size) {
     3.9      unsigned int retval = 0;
    3.10      
    3.11      const char* pgp_begin = "-----BEGIN PGP";
    3.12      size_t prefix_len = strlen(pgp_begin);
    3.13 +    size_t size_remaining = size;
    3.14 +    
    3.15      while (key_data) {
    3.16 -        key_data = strstr(key_data, pgp_begin);
    3.17 +        if (size_remaining <= prefix_len || key_data[0] == '\0')
    3.18 +            break;
    3.19 +        key_data = strnstr(key_data, pgp_begin, size_remaining);
    3.20          if (key_data) {
    3.21              retval++;
    3.22              key_data += prefix_len;
    3.23 +            size_remaining -= prefix_len;
    3.24          }
    3.25      }
    3.26      return retval;
    3.27 @@ -2004,7 +2009,7 @@
    3.28  PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
    3.29                                size_t size, identity_list **private_idents)
    3.30  {
    3.31 -    unsigned int keycount = count_keydata_parts(key_data);
    3.32 +    unsigned int keycount = count_keydata_parts(key_data, size);
    3.33      if (keycount < 2)
    3.34          return(_pgp_import_keydata(session, key_data, size, private_idents));
    3.35  
    3.36 @@ -2020,7 +2025,14 @@
    3.37      PEP_STATUS retval = PEP_KEY_IMPORTED;
    3.38      
    3.39      for (i = 0, curr_begin = key_data; i < keycount; i++) {
    3.40 -        const char* next_begin = strstr(curr_begin + prefix_len, pgp_begin);
    3.41 +        const char* next_begin = NULL;
    3.42 +
    3.43 +        // This is assured to be OK because the count function above 
    3.44 +        // made sure that THIS round contains at least prefix_len chars
    3.45 +        // We used strnstr to count, so we know that strstr will be ok.
    3.46 +        if (strlen(curr_begin + prefix_len) > prefix_len)
    3.47 +            next_begin = strstr(curr_begin + prefix_len, pgp_begin);
    3.48 +
    3.49          if (next_begin)
    3.50              curr_size = next_begin - curr_begin;
    3.51          else
     4.1 --- a/src/platform_unix.c	Thu Jul 04 10:52:32 2019 +0200
     4.2 +++ b/src/platform_unix.c	Mon Jul 08 16:44:35 2019 +0200
     4.3 @@ -198,6 +198,43 @@
     4.4      return retval;
     4.5  }
     4.6  
     4.7 +char *strnstr(const char *big, const char *little, size_t len) {
     4.8 +    if (big == NULL || little == NULL)
     4.9 +        return NULL;
    4.10 +        
    4.11 +    if (*little == '\0')
    4.12 +        return (char*)big;
    4.13 +        
    4.14 +    const char* curr_big = big;
    4.15 +    
    4.16 +    size_t little_len = strlen(little);
    4.17 +    size_t remaining = len;
    4.18 +
    4.19 +    const char* retval = NULL;
    4.20 +    
    4.21 +    for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
    4.22 +        // find first-char match
    4.23 +        if (*curr_big != *little) {
    4.24 +            continue;
    4.25 +        }
    4.26 +        retval = curr_big;
    4.27 +
    4.28 +        const char* inner_big = retval + 1;
    4.29 +        const char* curr_little = little + 1;
    4.30 +        int j;
    4.31 +        for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
    4.32 +            if (*inner_big != *curr_little) {
    4.33 +                retval = NULL;
    4.34 +                break;
    4.35 +            }    
    4.36 +        }
    4.37 +        if (retval)
    4.38 +            break;
    4.39 +    }
    4.40 +    return (char*)retval;
    4.41 +}
    4.42 +
    4.43 +
    4.44  #ifdef USE_NETPGP
    4.45  // FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
    4.46  int regnexec(const regex_t* preg, const char* string,
    4.47 @@ -449,4 +486,3 @@
    4.48      return NULL;
    4.49  }
    4.50  #endif
    4.51 -
     5.1 --- a/src/platform_unix.h	Thu Jul 04 10:52:32 2019 +0200
     5.2 +++ b/src/platform_unix.h	Mon Jul 08 16:44:35 2019 +0200
     5.3 @@ -67,6 +67,7 @@
     5.4  #if !defined(BSD) && !defined(__APPLE__)
     5.5  size_t strlcpy(char* dst, const	char* src, size_t size);
     5.6  size_t strlcat(char* dst, const	char* src, size_t size);
     5.7 +char *strnstr(const char *big, const char *little, size_t len);
     5.8  
     5.9  // N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
    5.10  //      the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is
     6.1 --- a/src/platform_windows.cpp	Thu Jul 04 10:52:32 2019 +0200
     6.2 +++ b/src/platform_windows.cpp	Mon Jul 08 16:44:35 2019 +0200
     6.3 @@ -283,6 +283,41 @@
     6.4      dst[start_len + size_to_copy] = '\0';
     6.5      return retval;
     6.6  }
     6.7 +char *strnstr(const char *big, const char *little, size_t len) {
     6.8 +    if (big == NULL || little == NULL)
     6.9 +        return NULL;
    6.10 +        
    6.11 +    if (*little == '\0')
    6.12 +        return (char*)big;
    6.13 +        
    6.14 +    const char* curr_big = big;
    6.15 +    
    6.16 +    size_t little_len = strlen(little);
    6.17 +    size_t remaining = len;
    6.18 +
    6.19 +    const char* retval = NULL;
    6.20 +    
    6.21 +    for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
    6.22 +        // find first-char match
    6.23 +        if (*curr_big != *little) {
    6.24 +            continue;
    6.25 +        }
    6.26 +        retval = curr_big;
    6.27 +
    6.28 +        const char* inner_big = retval + 1;
    6.29 +        const char* curr_little = little + 1;
    6.30 +        int j;
    6.31 +        for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
    6.32 +            if (*inner_big != *curr_little) {
    6.33 +                retval = NULL;
    6.34 +                break;
    6.35 +            }    
    6.36 +        }
    6.37 +        if (retval)
    6.38 +            break;
    6.39 +    }
    6.40 +    return (char*)retval;
    6.41 +}
    6.42  
    6.43  int mkstemp(char *templ)
    6.44  {
     7.1 --- a/src/platform_windows.h	Thu Jul 04 10:52:32 2019 +0200
     7.2 +++ b/src/platform_windows.h	Mon Jul 08 16:44:35 2019 +0200
     7.3 @@ -74,6 +74,8 @@
     7.4  
     7.5  size_t strlcpy(char* dst, const	char* src, size_t size);
     7.6  size_t strlcat(char* dst, const	char* src, size_t size);
     7.7 +char *strnstr(const char *big, const char *little, size_t len);
     7.8 +
     7.9  
    7.10  const char *windoze_local_db(void);
    7.11  const char *windoze_system_db(void);
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/include/StrnstrTests.h	Mon Jul 08 16:44:35 2019 +0200
     8.3 @@ -0,0 +1,35 @@
     8.4 +// This file is under GNU General Public License 3.0
     8.5 +// see LICENSE.txt
     8.6 +
     8.7 +#ifndef STRNSTR_H
     8.8 +#define STRNSTR_H
     8.9 +
    8.10 +#include <string>
    8.11 +#include "EngineTestIndividualSuite.h"
    8.12 +
    8.13 +using namespace std;
    8.14 +
    8.15 +class StrnstrTests : public EngineTestIndividualSuite {
    8.16 +    public:
    8.17 +        StrnstrTests(string test_suite, string test_home_dir);
    8.18 +    private:
    8.19 +        void check_strnstr_equal();
    8.20 +        void check_strnstr_first_null();
    8.21 +        void check_strnstr_second_null();
    8.22 +        void check_strnstr_both_null();
    8.23 +        void check_strnstr_first_empty();
    8.24 +        void check_strnstr_second_empty();
    8.25 +        void check_strnstr_both_empty();
    8.26 +        void check_strnstr_first_letter_only();
    8.27 +        void check_strnstr_first_two_only();
    8.28 +        void check_strnstr_all_but_last();
    8.29 +        void check_strnstr_same_len_all_but_last();
    8.30 +        void check_strnstr_same_len_none();
    8.31 +        void check_strnstr_same_big_smaller();
    8.32 +        void check_strnstr_shift_one_no_match();
    8.33 +        void check_strnstr_shift_to_end();
    8.34 +        void check_strnstr_match_after_end();
    8.35 +        void check_strnstr_equal_but_size_too_small();
    8.36 +};
    8.37 +
    8.38 +#endif
     9.1 --- a/test/src/SuiteMaker.cc	Thu Jul 04 10:52:32 2019 +0200
     9.2 +++ b/test/src/SuiteMaker.cc	Mon Jul 08 16:44:35 2019 +0200
     9.3 @@ -71,6 +71,7 @@
     9.4  #include "KeyAttachmentTests.h"
     9.5  #include "OwnKeysRetrieveTests.h"
     9.6  #include "TrustManipulationTests.h"
     9.7 +#include "StrnstrTests.h"
     9.8  #include "SyncTests.h"
     9.9  #include "RevocationTests.h"
    9.10  #include "AppleMailTests.h"
    9.11 @@ -136,13 +137,14 @@
    9.12      "KeyAttachmentTests",
    9.13      "OwnKeysRetrieveTests",
    9.14      "TrustManipulationTests",
    9.15 +    "StrnstrTests",
    9.16      "SyncTests",
    9.17      "RevocationTests",
    9.18      "AppleMailTests",
    9.19  };
    9.20  
    9.21  // This file is generated, so magic constants are ok.
    9.22 -int SuiteMaker::num_suites = 62;
    9.23 +int SuiteMaker::num_suites = 63;
    9.24  
    9.25  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
    9.26      if (strcmp(test_class_name, "URIAddressTests") == 0)
    9.27 @@ -263,6 +265,8 @@
    9.28          *test_suite = new OwnKeysRetrieveTests(test_class_name, test_home);
    9.29      else if (strcmp(test_class_name, "TrustManipulationTests") == 0)
    9.30          *test_suite = new TrustManipulationTests(test_class_name, test_home);
    9.31 +    else if (strcmp(test_class_name, "StrnstrTests") == 0)
    9.32 +        *test_suite = new StrnstrTests(test_class_name, test_home);
    9.33      else if (strcmp(test_class_name, "SyncTests") == 0)
    9.34          *test_suite = new SyncTests(test_class_name, test_home);
    9.35      else if (strcmp(test_class_name, "RevocationTests") == 0)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/test/src/engine_tests/StrnstrTests.cc	Mon Jul 08 16:44:35 2019 +0200
    10.3 @@ -0,0 +1,154 @@
    10.4 +// This file is under GNU General Public License 3.0
    10.5 +// see LICENSE.txt
    10.6 +
    10.7 +#include <stdlib.h>
    10.8 +#include <cstring>
    10.9 +#include <string>
   10.10 +
   10.11 +#include <cpptest.h>
   10.12 +#include "test_util.h"
   10.13 +
   10.14 +#include "pEpEngine.h"
   10.15 +#include "platform_unix.h"
   10.16 +
   10.17 +#include "EngineTestIndividualSuite.h"
   10.18 +#include "StrnstrTests.h"
   10.19 +
   10.20 +using namespace std;
   10.21 +
   10.22 +StrnstrTests::StrnstrTests(string suitename, string test_home_dir) :
   10.23 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   10.24 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal"),
   10.25 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_equal)));
   10.26 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_empty"),
   10.27 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_empty)));
   10.28 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_second_empty"),
   10.29 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_second_empty)));
   10.30 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_both_empty"),
   10.31 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_both_empty)));
   10.32 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_letter_only"),
   10.33 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_letter_only)));
   10.34 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_two_only"),
   10.35 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_two_only)));
   10.36 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_all_but_last"),
   10.37 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_all_but_last)));
   10.38 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_all_but_last"),
   10.39 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_len_all_but_last)));
   10.40 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_none"),
   10.41 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_len_none)));
   10.42 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_big_smaller"),
   10.43 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_big_smaller)));
   10.44 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_one_no_match"),
   10.45 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_shift_one_no_match)));
   10.46 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_to_end"),
   10.47 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_shift_to_end)));
   10.48 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_match_after_end"),
   10.49 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_match_after_end)));
   10.50 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal_but_size_too_small"),
   10.51 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_equal_but_size_too_small)));
   10.52 +}
   10.53 +
   10.54 +void StrnstrTests::check_strnstr_equal() {
   10.55 +    const char* big = "Bob123";
   10.56 +    const char* little = "Bob123";
   10.57 +    size_t size = strlen(big);
   10.58 +    const char* result = strnstr(big, little, size);
   10.59 +    TEST_ASSERT_MSG(result == big, result);
   10.60 +}
   10.61 +
   10.62 +void StrnstrTests::check_strnstr_first_empty() {
   10.63 +    const char* big = "";
   10.64 +    const char* little = "Bob123";
   10.65 +    size_t size = strlen(big);
   10.66 +    const char* result = strnstr(big, little, size);
   10.67 +    TEST_ASSERT_MSG(result == NULL, result);
   10.68 +}
   10.69 +void StrnstrTests::check_strnstr_second_empty() {
   10.70 +    const char* big = "YerMama";
   10.71 +    const char* little = "";
   10.72 +    size_t size = strlen(big);
   10.73 +    const char* result = strnstr(big, little, size);
   10.74 +    TEST_ASSERT_MSG(result == big, result);
   10.75 +    TEST_ASSERT(true);
   10.76 +}
   10.77 +
   10.78 +void StrnstrTests::check_strnstr_both_empty() {
   10.79 +    const char* big = "";
   10.80 +    const char* little = "";
   10.81 +    size_t size = strlen(big);
   10.82 +    const char* result = strnstr(big, little, size);
   10.83 +    TEST_ASSERT_MSG(result == big, result);
   10.84 +    TEST_ASSERT(true);
   10.85 +}
   10.86 +
   10.87 +void StrnstrTests::check_strnstr_first_letter_only() {
   10.88 +    const char* big = "Bob123";
   10.89 +    const char* little = "Beef";
   10.90 +    size_t size = strlen(big);
   10.91 +    const char* result = strnstr(big, little, size);
   10.92 +    TEST_ASSERT_MSG(result == NULL, result);    
   10.93 +}
   10.94 +void StrnstrTests::check_strnstr_first_two_only() {
   10.95 +    const char* big = "Bob123";
   10.96 +    const char* little = "Boof";
   10.97 +    size_t size = strlen(big);
   10.98 +    const char* result = strnstr(big, little, size);
   10.99 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.100 +}
  10.101 +void StrnstrTests::check_strnstr_all_but_last() {
  10.102 +    const char* big = "BeesBeesBees";
  10.103 +    const char* little = "Beef";
  10.104 +    size_t size = strlen(big);
  10.105 +    const char* result = strnstr(big, little, size);
  10.106 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.107 +}
  10.108 +void StrnstrTests::check_strnstr_same_len_all_but_last() {
  10.109 +    const char* big = "Bees";
  10.110 +    const char* little = "Beef";
  10.111 +    size_t size = strlen(big);
  10.112 +    const char* result = strnstr(big, little, size);
  10.113 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.114 +}
  10.115 +void StrnstrTests::check_strnstr_same_len_none() {
  10.116 +    const char* big = "1234";
  10.117 +    const char* little = "Beef";
  10.118 +    size_t size = strlen(big);
  10.119 +    const char* result = strnstr(big, little, size);
  10.120 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.121 +}
  10.122 +void StrnstrTests::check_strnstr_same_big_smaller() {
  10.123 +    const char* big = "Bee";
  10.124 +    const char* little = "Bees";
  10.125 +    size_t size = strlen(big);
  10.126 +    const char* result = strnstr(big, little, size);
  10.127 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.128 +}
  10.129 +void StrnstrTests::check_strnstr_shift_one_no_match() {
  10.130 +    const char* big = "1Bee";
  10.131 +    const char* little = "Bees";
  10.132 +    size_t size = strlen(big);
  10.133 +    const char* result = strnstr(big, little, size);
  10.134 +    TEST_ASSERT_MSG(result == NULL, result);    
  10.135 +}
  10.136 +void StrnstrTests::check_strnstr_shift_to_end() {
  10.137 +    const char* big = "BigBeeWithExtraBeef";
  10.138 +    const char* little = "Beef";
  10.139 +    size_t size = strlen(big);
  10.140 +    const char* result = strnstr(big, little, size);
  10.141 +    TEST_ASSERT_MSG(result == big + 15, result);    
  10.142 +    TEST_ASSERT(true);
  10.143 +}
  10.144 +void StrnstrTests::check_strnstr_match_after_end() {
  10.145 +    const char* big = "EatMoreBeef";
  10.146 +    const char* little = "Beef";
  10.147 +    size_t size = strlen(big);
  10.148 +    const char* result = strnstr(big, little, size - 1);
  10.149 +    TEST_ASSERT_MSG(result == NULL, result);
  10.150 +}
  10.151 +void StrnstrTests::check_strnstr_equal_but_size_too_small() {
  10.152 +    const char* big = "Bob123";
  10.153 +    const char* little = "Bob123";
  10.154 +    size_t size = strlen(big);
  10.155 +    const char* result = strnstr(big, little, size - 1);
  10.156 +    TEST_ASSERT_MSG(result == NULL, result);
  10.157 +}