make map_name() interpret empty strings as "no separator"

empty strings were previously meaningless, and starting with 72c2d695a,
failure to handle them lead to bogus results when the IMAP hierarchy
separator is legitimately empty (when the server genuinely supports none
and none is manually configured). non-null can be asserted more cleanly
than null-or-non-empty, so change the api like that.
incidentally, this also removes the need to work around gcc's bogus
warning in -Os mode.

problem found by "Casper Ti. Vector" <caspervector@gmail.com>
This commit is contained in:
Oswald Buddenhagen 2017-10-15 16:14:20 +02:00
parent 53e8e79488
commit c29eceaeed
4 changed files with 15 additions and 20 deletions

View File

@ -355,6 +355,8 @@ load_config( const char *where, int pseudo )
if (store) { if (store) {
if (!store->max_size) if (!store->max_size)
store->max_size = INT_MAX; store->max_size = INT_MAX;
if (!store->flat_delim)
store->flat_delim = "";
*storeapp = store; *storeapp = store;
storeapp = &store->next; storeapp = &store->next;
*storeapp = 0; *storeapp = 0;

View File

@ -983,7 +983,7 @@ store_connected( int sts, void *aux )
flags |= LIST_INBOX; flags |= LIST_INBOX;
} else if (c == '/') { } else if (c == '/') {
/* Flattened sub-folders of INBOX actually end up in Path. */ /* Flattened sub-folders of INBOX actually end up in Path. */
if (mvars->ctx[t]->conf->flat_delim) if (mvars->ctx[t]->conf->flat_delim[0])
flags |= LIST_PATH; flags |= LIST_PATH;
else else
flags |= LIST_INBOX; flags |= LIST_INBOX;
@ -1027,7 +1027,7 @@ store_listed( int sts, string_list_t *boxes, void *aux )
return; return;
case DRV_OK: case DRV_OK:
for (box = boxes; box; box = box->next) { for (box = boxes; box; box = box->next) {
if (mvars->ctx[t]->conf->flat_delim) { if (mvars->ctx[t]->conf->flat_delim[0]) {
string_list_t *nbox; string_list_t *nbox;
if (map_name( box->string, (char **)&nbox, offsetof(string_list_t, string), mvars->ctx[t]->conf->flat_delim, "/" ) < 0) { if (map_name( box->string, (char **)&nbox, offsetof(string_list_t, string), mvars->ctx[t]->conf->flat_delim, "/" ) < 0) {
error( "Error: flattened mailbox name '%s' contains canonical hierarchy delimiter\n", box->string ); error( "Error: flattened mailbox name '%s' contains canonical hierarchy delimiter\n", box->string );

View File

@ -1014,7 +1014,7 @@ sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t *
svars->orig_name[t] = svars->orig_name[t] =
(!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ? (!names[t] || (ctx[t]->conf->map_inbox && !strcmp( ctx[t]->conf->map_inbox, names[t] ))) ?
"INBOX" : names[t]; "INBOX" : names[t];
if (!ctx[t]->conf->flat_delim) { if (!ctx[t]->conf->flat_delim[0]) {
svars->box_name[t] = nfstrdup( svars->orig_name[t] ); svars->box_name[t] = nfstrdup( svars->orig_name[t] );
} else if (map_name( svars->orig_name[t], &svars->box_name[t], 0, "/", ctx[t]->conf->flat_delim ) < 0) { } else if (map_name( svars->orig_name[t], &svars->box_name[t], 0, "/", ctx[t]->conf->flat_delim ) < 0) {
error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", svars->orig_name[t] ); error( "Error: canonical mailbox name '%s' contains flattened hierarchy delimiter\n", svars->orig_name[t] );

View File

@ -479,19 +479,20 @@ map_name( const char *arg, char **result, int reserve, const char *in, const cha
char *p; char *p;
int i, l, ll, num, inl, outl; int i, l, ll, num, inl, outl;
assert( arg );
l = strlen( arg ); l = strlen( arg );
if (!in) { assert( in );
inl = strlen( in );
if (!inl) {
copy: copy:
*result = nfmalloc( reserve + l + 1 ); *result = nfmalloc( reserve + l + 1 );
memcpy( *result + reserve, arg, l + 1 ); memcpy( *result + reserve, arg, l + 1 );
return 0; return 0;
} }
inl = strlen( in ); assert( out );
if (out) {
outl = strlen( out ); outl = strlen( out );
if (inl == outl && !memcmp( in, out, inl )) if (inl == outl && !memcmp( in, out, inl ))
goto copy; goto copy;
}
for (num = 0, i = 0; i < l; ) { for (num = 0, i = 0; i < l; ) {
for (ll = 0; ll < inl; ll++) for (ll = 0; ll < inl; ll++)
if (arg[i + ll] != in[ll]) if (arg[i + ll] != in[ll])
@ -500,7 +501,7 @@ map_name( const char *arg, char **result, int reserve, const char *in, const cha
i += inl; i += inl;
continue; continue;
fout: fout:
if (out) { if (outl) {
for (ll = 0; ll < outl; ll++) for (ll = 0; ll < outl; ll++)
if (arg[i + ll] != out[ll]) if (arg[i + ll] != out[ll])
goto fnexti; goto fnexti;
@ -511,7 +512,7 @@ map_name( const char *arg, char **result, int reserve, const char *in, const cha
} }
if (!num) if (!num)
goto copy; goto copy;
if (!out) if (!outl)
return -2; return -2;
*result = nfmalloc( reserve + l + num * (outl - inl) + 1 ); *result = nfmalloc( reserve + l + num * (outl - inl) + 1 );
p = *result + reserve; p = *result + reserve;
@ -519,15 +520,7 @@ map_name( const char *arg, char **result, int reserve, const char *in, const cha
for (ll = 0; ll < inl; ll++) for (ll = 0; ll < inl; ll++)
if (arg[i + ll] != in[ll]) if (arg[i + ll] != in[ll])
goto rnexti; goto rnexti;
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__clang__)
# pragma GCC diagnostic push
/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42145 */
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
memcpy( p, out, outl ); memcpy( p, out, outl );
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && !defined(__clang__)
# pragma GCC diagnostic pop
#endif
p += outl; p += outl;
i += inl; i += inl;
continue; continue;