mirror of
https://github.com/deltachat/deltachat-core.git
synced 2025-10-05 19:42:04 +02:00
collect functions working with addresses in dc_contact
This commit is contained in:
parent
47f069f868
commit
e6eb4eff3e
9 changed files with 99 additions and 96 deletions
|
@ -115,7 +115,7 @@ static int add_attribute(dc_aheader_t* aheader, const char* name, const char* va
|
|||
|| aheader->addr /* email already given */) {
|
||||
return 0;
|
||||
}
|
||||
aheader->addr = dc_normalize_addr(value);
|
||||
aheader->addr = dc_addr_normalize(value);
|
||||
return 1;
|
||||
}
|
||||
#if 0 /* autocrypt 11/2017 no longer uses the type attribute and it will make the autocrypt header invalid */
|
||||
|
@ -289,7 +289,7 @@ dc_aheader_t* dc_aheader_new_from_imffields(const char* wanted_from, const struc
|
|||
/* header found, check if it is valid and matched the wanted address */
|
||||
dc_aheader_t* test = dc_aheader_new();
|
||||
if (!dc_aheader_set_from_string(test, optional_field->fld_value)
|
||||
|| strcasecmp(test->addr, wanted_from)!=0) {
|
||||
|| dc_addr_cmp(test->addr, wanted_from)!=0) {
|
||||
dc_aheader_unref(test);
|
||||
test = NULL;
|
||||
}
|
||||
|
|
129
src/dc_contact.c
129
src/dc_contact.c
|
@ -34,7 +34,6 @@
|
|||
* objects using dc_get_contact().
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*
|
||||
* @return The contact object. Must be freed using dc_contact_unref() when done.
|
||||
*/
|
||||
dc_contact_t* dc_contact_new(dc_context_t* context)
|
||||
|
@ -56,9 +55,7 @@ dc_contact_t* dc_contact_new(dc_context_t* context)
|
|||
* Free a contact object.
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object as created eg. by dc_get_contact().
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void dc_contact_unref(dc_contact_t* contact)
|
||||
|
@ -79,9 +76,7 @@ void dc_contact_unref(dc_contact_t* contact)
|
|||
* use dc_contact_unref().
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object to free.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void dc_contact_empty(dc_contact_t* contact)
|
||||
|
@ -115,9 +110,7 @@ void dc_contact_empty(dc_contact_t* contact)
|
|||
* Get the ID of the contact.
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return the ID of the contact, 0 on errors.
|
||||
*/
|
||||
uint32_t dc_contact_get_id(const dc_contact_t* contact)
|
||||
|
@ -133,9 +126,7 @@ uint32_t dc_contact_get_id(const dc_contact_t* contact)
|
|||
* Get email address. The email address is always set for a contact.
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return String with the email address, must be free()'d. Never returns NULL.
|
||||
*/
|
||||
char* dc_contact_get_addr(const dc_contact_t* contact)
|
||||
|
@ -157,9 +148,7 @@ char* dc_contact_get_addr(const dc_contact_t* contact)
|
|||
* To get a fine name to display in lists etc., use dc_contact_get_display_name() or dc_contact_get_name_n_addr().
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return String with the name to display, must be free()'d. Empty string if unset, never returns NULL.
|
||||
*/
|
||||
char* dc_contact_get_name(const dc_contact_t* contact)
|
||||
|
@ -180,9 +169,7 @@ char* dc_contact_get_name(const dc_contact_t* contact)
|
|||
* To get the name editable in a formular, use dc_contact_get_name().
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return String with the name to display, must be free()'d. Never returns NULL.
|
||||
*/
|
||||
char* dc_contact_get_display_name(const dc_contact_t* contact)
|
||||
|
@ -211,9 +198,7 @@ char* dc_contact_get_display_name(const dc_contact_t* contact)
|
|||
* The summary must not be spreaded via mail (To:, CC: ...) as it as it may contain sth. like "Daddy".
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return Summary string, must be free()'d. Never returns NULL.
|
||||
*/
|
||||
char* dc_contact_get_name_n_addr(const dc_contact_t* contact)
|
||||
|
@ -236,9 +221,7 @@ char* dc_contact_get_name_n_addr(const dc_contact_t* contact)
|
|||
* If the display name is not set, the e-mail address is returned.
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return String with the name to display, must be free()'d. Never returns NULL.
|
||||
*/
|
||||
char* dc_contact_get_first_name(const dc_contact_t* contact)
|
||||
|
@ -261,9 +244,7 @@ char* dc_contact_get_first_name(const dc_contact_t* contact)
|
|||
* To block or unblock a contact, use dc_block_contact().
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return 1=contact is blocked, 0=contact is not blocked.
|
||||
*/
|
||||
int dc_contact_is_blocked(const dc_contact_t* contact)
|
||||
|
@ -302,9 +283,7 @@ cleanup:
|
|||
* The UI may draw a checkbox or sth. like that beside verified contacts.
|
||||
*
|
||||
* @memberof dc_contact_t
|
||||
*
|
||||
* @param contact The contact object.
|
||||
*
|
||||
* @return 0: contact is not verified.
|
||||
* 2: SELF and contact have verified their fingerprints in both directions; in the UI typically checkmarks are shown.
|
||||
*/
|
||||
|
@ -338,9 +317,7 @@ cleanup:
|
|||
* If there is no space in the string, the whole string is returned.
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*
|
||||
* @param full_name Full name of the contact.
|
||||
*
|
||||
* @return String with the first name, must be free()'d after usage.
|
||||
*/
|
||||
char* dc_get_first_name(const char* full_name)
|
||||
|
@ -375,10 +352,8 @@ char* dc_get_first_name(const char* full_name)
|
|||
* Typically, this function is not needed as it is called implicitly by dc_add_address_book()
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*
|
||||
* @param full_name Buffer with the name, is modified during processing; the
|
||||
* resulting string may be shorter but never longer.
|
||||
*
|
||||
* @return None. But the given buffer may be modified.
|
||||
*/
|
||||
void dc_normalize_name(char* full_name)
|
||||
|
@ -418,35 +393,6 @@ void dc_normalize_name(char* full_name)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Normalize an email address.
|
||||
*
|
||||
* Normalization includes:
|
||||
* - removing `mailto:` prefix
|
||||
*
|
||||
* Not sure if we should also unifiy international characters before the @,
|
||||
* see also https://autocrypt.readthedocs.io/en/latest/address-canonicalization.html
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*
|
||||
* @param email_addr__ The email address to normalize.
|
||||
*
|
||||
* @return The normalized email address, must be free()'d. NULL is never returned.
|
||||
*/
|
||||
char* dc_normalize_addr(const char* email_addr__)
|
||||
{
|
||||
char* addr = dc_strdup(email_addr__);
|
||||
dc_trim(addr);
|
||||
if (strncmp(addr, "mailto:", 7)==0) {
|
||||
char* old = addr;
|
||||
addr = dc_strdup(&old[7]);
|
||||
free(old);
|
||||
dc_trim(addr);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Library-internal.
|
||||
*
|
||||
|
@ -498,12 +444,63 @@ cleanup:
|
|||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Working with e-mail-addresses
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Normalize an email address.
|
||||
*
|
||||
* Normalization includes:
|
||||
* - Trimming
|
||||
* - removing `mailto:` prefix
|
||||
*
|
||||
* Not sure if we should also unifiy international characters before the @,
|
||||
* see also https://autocrypt.readthedocs.io/en/latest/address-canonicalization.html
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
* @param addr The email address to normalize.
|
||||
* @return The normalized email address, must be free()'d. NULL is never returned.
|
||||
*/
|
||||
char* dc_addr_normalize(const char* addr)
|
||||
{
|
||||
char* addr_normalized = dc_strdup(addr);
|
||||
dc_trim(addr_normalized);
|
||||
if (strncmp(addr_normalized, "mailto:", 7)==0) {
|
||||
char* old = addr_normalized;
|
||||
addr_normalized = dc_strdup(&old[7]);
|
||||
free(old);
|
||||
dc_trim(addr_normalized);
|
||||
}
|
||||
return addr_normalized;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two e-mail-addresses.
|
||||
* The adresses will be normalized before compare and the comparison is case-insensitive.
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
* @return 0: addresses are equal, >0: addr1 is larger than addr2, <0: addr1 is smaller than addr2
|
||||
*/
|
||||
int dc_addr_cmp(const char* addr1, const char* addr2)
|
||||
{
|
||||
char* norm1 = dc_addr_normalize(addr1);
|
||||
char* norm2 = dc_addr_normalize(addr2);
|
||||
int ret = strcasecmp(addr1, addr2);
|
||||
free(norm1);
|
||||
free(norm2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a given e-mail-address is equal to the configured-self-address.
|
||||
*
|
||||
* @private @memberof dc_contact_t
|
||||
*/
|
||||
int dc_addr_is_self(dc_context_t* context, const char* addr)
|
||||
int dc_addr_equals_self(dc_context_t* context, const char* addr)
|
||||
{
|
||||
int ret = 0;
|
||||
char* normalized_addr = NULL;
|
||||
|
@ -513,7 +510,7 @@ int dc_addr_is_self(dc_context_t* context, const char* addr)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
normalized_addr = dc_normalize_addr(addr);
|
||||
normalized_addr = dc_addr_normalize(addr);
|
||||
|
||||
if (NULL==(self_addr=dc_sqlite3_get_config(context->sql, "configured_addr", NULL))) {
|
||||
goto cleanup;
|
||||
|
@ -526,3 +523,23 @@ cleanup:
|
|||
free(normalized_addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int dc_addr_equals_contact(dc_context_t* context, const char* addr, uint32_t contact_id)
|
||||
{
|
||||
int addr_are_equal = 0;
|
||||
if (addr) {
|
||||
dc_contact_t* contact = dc_contact_new(context);
|
||||
if (dc_contact_load_from_db(contact, context->sql, contact_id)) {
|
||||
if (contact->addr) {
|
||||
char* normalized_addr = dc_addr_normalize(addr);
|
||||
if (strcasecmp(contact->addr, normalized_addr)==0) {
|
||||
addr_are_equal = 1;
|
||||
}
|
||||
free(normalized_addr);
|
||||
}
|
||||
}
|
||||
dc_contact_unref(contact);
|
||||
}
|
||||
return addr_are_equal;
|
||||
}
|
||||
|
|
|
@ -78,12 +78,17 @@ struct _dc_contact
|
|||
#define DC_ORIGIN_MIN_VERIFIED (DC_ORIGIN_INCOMING_REPLY_TO) /* contacts with at least this origin value are verified and known not to be spam */
|
||||
#define DC_ORIGIN_MIN_START_NEW_NCHAT (0x7FFFFFFF) /* contacts with at least this origin value start a new "normal" chat, defaults to off */
|
||||
|
||||
int dc_contact_load_from_db (dc_contact_t*, dc_sqlite3_t*, uint32_t contact_id);
|
||||
int dc_contact_n_peerstate_are_verified(const dc_contact_t*, const dc_apeerstate_t*);
|
||||
void dc_normalize_name (char* full_name);
|
||||
char* dc_normalize_addr (const char* email_addr);
|
||||
char* dc_get_first_name (const char* full_name);
|
||||
int dc_addr_is_self (dc_context_t*, const char* addr);
|
||||
|
||||
int dc_contact_load_from_db (dc_contact_t*, dc_sqlite3_t*, uint32_t contact_id);
|
||||
int dc_contact_n_peerstate_are_verified (const dc_contact_t*, const dc_apeerstate_t*);
|
||||
|
||||
void dc_normalize_name (char* full_name);
|
||||
char* dc_get_first_name (const char* full_name);
|
||||
|
||||
int dc_addr_cmp (const char* addr1, const char* addr2);
|
||||
char* dc_addr_normalize (const char* addr);
|
||||
int dc_addr_equals_self (dc_context_t*, const char* addr);
|
||||
int dc_addr_equals_contact (dc_context_t*, const char* addr, uint32_t contact_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -2901,7 +2901,7 @@ uint32_t dc_add_or_lookup_contact( dc_context_t* context,
|
|||
|
||||
/* normalize the email-address:
|
||||
- remove leading `mailto:` */
|
||||
addr = dc_normalize_addr(addr__);
|
||||
addr = dc_addr_normalize(addr__);
|
||||
|
||||
/* rough check if email-address is valid */
|
||||
if (strlen(addr) < 3 || strchr(addr, '@')==NULL || strchr(addr, '.')==NULL) {
|
||||
|
@ -3614,24 +3614,6 @@ cleanup:
|
|||
}
|
||||
|
||||
|
||||
int dc_contact_addr_equals(dc_context_t* context, uint32_t contact_id, const char* other_addr)
|
||||
{
|
||||
int addr_are_equal = 0;
|
||||
if (other_addr) {
|
||||
dc_contact_t* contact = dc_contact_new(context);
|
||||
if (dc_contact_load_from_db(contact, context->sql, contact_id)) {
|
||||
if (contact->addr) {
|
||||
if (strcasecmp(contact->addr, other_addr)==0) {
|
||||
addr_are_equal = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
dc_contact_unref(contact);
|
||||
}
|
||||
return addr_are_equal;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Handle Messages
|
||||
******************************************************************************/
|
||||
|
|
|
@ -135,7 +135,6 @@ uint32_t dc_add_or_lookup_contact (dc_context_t*, const
|
|||
int dc_get_contact_origin (dc_context_t*, uint32_t id, int* ret_blocked);
|
||||
int dc_is_contact_blocked (dc_context_t*, uint32_t id);
|
||||
int dc_real_contact_exists (dc_context_t*, uint32_t id);
|
||||
int dc_contact_addr_equals (dc_context_t*, uint32_t contact_id, const char* other_addr);
|
||||
void dc_scaleup_contact_origin (dc_context_t*, uint32_t contact_id, int origin);
|
||||
void dc_unarchive_chat (dc_context_t*, uint32_t chat_id);
|
||||
size_t dc_get_chat_cnt (dc_context_t*);
|
||||
|
|
|
@ -415,7 +415,7 @@ static void mailimf_get_recipients__add_addr(dc_hash_t* recipients, struct maili
|
|||
{
|
||||
/* only used internally by mailimf_get_recipients() */
|
||||
if (mb) {
|
||||
char* addr_norm = dc_normalize_addr(mb->mb_addr_spec);
|
||||
char* addr_norm = dc_addr_normalize(mb->mb_addr_spec);
|
||||
dc_hash_insert(recipients, addr_norm, strlen(addr_norm), (void*)1);
|
||||
free(addr_norm);
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ char* mailimf_find_first_addr(const struct mailimf_mailbox_list* mb_list)
|
|||
for (cur = clist_begin(mb_list->mb_list); cur!=NULL ; cur=clist_next(cur)) {
|
||||
struct mailimf_mailbox* mb = (struct mailimf_mailbox*)clist_content(cur);
|
||||
if (mb && mb->mb_addr_spec) {
|
||||
return dc_normalize_addr(mb->mb_addr_spec);
|
||||
return dc_addr_normalize(mb->mb_addr_spec);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -1878,7 +1878,7 @@ int dc_mimeparser_sender_equals_recipient(dc_mimeparser_t* mimeparser)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
from_addr_norm = dc_normalize_addr(mb->mb_addr_spec);
|
||||
from_addr_norm = dc_addr_normalize(mb->mb_addr_spec);
|
||||
|
||||
/* get To:/Cc: and check there is exactly one recipent */
|
||||
recipients = mailimf_get_recipients(mimeparser->header_root);
|
||||
|
|
|
@ -176,7 +176,7 @@ dc_lot_t* dc_check_qr(dc_context_t* context, const char* qr)
|
|||
|
||||
if (addr) {
|
||||
char* temp = dc_urldecode(addr); free(addr); addr = temp; /* urldecoding is needed at least for OPENPGP4FPR but should not hurt in the other cases */
|
||||
temp = dc_normalize_addr(addr); free(addr); addr = temp;
|
||||
temp = dc_addr_normalize(addr); free(addr); addr = temp;
|
||||
|
||||
if (strlen(addr) < 3 || strchr(addr, '@')==NULL || strchr(addr, '.')==NULL) {
|
||||
qr_parsed->state = DC_QR_ERROR;
|
||||
|
|
|
@ -49,7 +49,7 @@ static void add_or_lookup_contact_by_addr(dc_context_t* context, const char* dis
|
|||
*check_self = 0;
|
||||
|
||||
char* self_addr = dc_sqlite3_get_config(context->sql, "configured_addr", "");
|
||||
if (strcasecmp(self_addr, addr_spec)==0) {
|
||||
if (dc_addr_cmp(self_addr, addr_spec)==0) {
|
||||
*check_self = 1;
|
||||
}
|
||||
free(self_addr);
|
||||
|
@ -800,7 +800,7 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
|
|||
&& grpid
|
||||
&& grpname
|
||||
&& X_MrRemoveFromGrp==NULL /*otherwise, a pending "quit" message may pop up*/
|
||||
&& (!group_explicitly_left || (X_MrAddToGrp&&strcasecmp(self_addr,X_MrAddToGrp)==0)) /*re-create explicitly left groups only if ourself is re-added*/
|
||||
&& (!group_explicitly_left || (X_MrAddToGrp&&dc_addr_cmp(self_addr,X_MrAddToGrp)==0)) /*re-create explicitly left groups only if ourself is re-added*/
|
||||
)
|
||||
{
|
||||
int create_verified = 0;
|
||||
|
@ -886,13 +886,13 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
|
|||
sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
if (skip==NULL || strcasecmp(self_addr, skip) != 0) {
|
||||
if (skip==NULL || dc_addr_cmp(self_addr, skip) != 0) {
|
||||
dc_add_to_chat_contacts_table(context, chat_id, DC_CONTACT_ID_SELF);
|
||||
}
|
||||
|
||||
if (from_id > DC_CONTACT_ID_LAST_SPECIAL) {
|
||||
if (dc_contact_addr_equals(context, from_id, self_addr)==0
|
||||
&& (skip==NULL || dc_contact_addr_equals(context, from_id, skip)==0)) {
|
||||
if (dc_addr_equals_contact(context, self_addr, from_id)==0
|
||||
&& (skip==NULL || dc_addr_equals_contact(context, skip, from_id)==0)) {
|
||||
dc_add_to_chat_contacts_table(context, chat_id, from_id);
|
||||
}
|
||||
}
|
||||
|
@ -900,8 +900,8 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
|
|||
for (i = 0; i < to_ids_cnt; i++)
|
||||
{
|
||||
uint32_t to_id = dc_array_get_id(to_ids, i); /* to_id is only once in to_ids and is non-special */
|
||||
if (dc_contact_addr_equals(context, to_id, self_addr)==0
|
||||
&& (skip==NULL || dc_contact_addr_equals(context, to_id, skip)==0)) {
|
||||
if (dc_addr_equals_contact(context, self_addr, to_id)==0
|
||||
&& (skip==NULL || dc_addr_equals_contact(context, skip, to_id)==0)) {
|
||||
dc_add_to_chat_contacts_table(context, chat_id, to_id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -740,7 +740,7 @@ int dc_handle_securejoin_handshake(dc_context_t* context, dc_mimeparser_t* mimep
|
|||
context->cb(context, DC_EVENT_CONTACTS_CHANGED, 0/*no select event*/, 0);
|
||||
|
||||
if (join_vg) {
|
||||
if (!dc_addr_is_self(context, lookup_field(mimeparser, "Chat-Group-Member-Added"))) {
|
||||
if (!dc_addr_equals_self(context, lookup_field(mimeparser, "Chat-Group-Member-Added"))) {
|
||||
dc_log_info(context, 0, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group).");
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue