Browse Source

add input length argument to map_name()

... and use it when parsing IMAP LIST responses.
wip/maildir-path-under-inbox
Oswald Buddenhagen 3 years ago
parent
commit
bc3145617a
  1. 2
      src/common.h
  2. 6
      src/drv_imap.c
  3. 2
      src/main_sync.c
  4. 2
      src/sync.c
  5. 14
      src/util.c

2
src/common.h

@ -242,7 +242,7 @@ int ATTR_PRINTFLIKE(3, 4) nfsnprintf( char *buf, int blen, const char *fmt, ...
void ATTR_NORETURN oob( void ); void ATTR_NORETURN oob( void );
void ATTR_NORETURN oom( void ); void ATTR_NORETURN oom( void );
int map_name( const char *arg, char **result, uint reserve, const char *in, const char *out ); int map_name( const char *arg, int argl, char **result, uint reserve, const char *in, const char *out );
int mkdir_p( char *path, int len ); int mkdir_p( char *path, int len );

6
src/drv_imap.c

@ -1491,8 +1491,8 @@ parse_list_rsp_p2( imap_store_t *ctx, list_t *list )
} }
if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */ if (argl >= 5 && !memcmp( arg + argl - 5, ".lock", 5 )) /* workaround broken servers */
return LIST_OK; return LIST_OK;
if (map_name( arg, (char **)&narg, offsetof(string_list_t, string), ctx->delimiter, "/") < 0) { if (map_name( arg, argl, (char **)&narg, offsetof(string_list_t, string), ctx->delimiter, "/") < 0) {
warn( "IMAP warning: ignoring mailbox %s (reserved character '/' in name)\n", arg ); warn( "IMAP warning: ignoring mailbox %.*s (reserved character '/' in name)\n", argl, arg );
return LIST_OK; return LIST_OK;
} }
// Validate the normalized name. Technically speaking, we could tolerate // Validate the normalized name. Technically speaking, we could tolerate
@ -1533,7 +1533,7 @@ prepare_name( char **buf, const imap_store_t *ctx, const char *prefix, const cha
{ {
uint pl = strlen( prefix ); uint pl = strlen( prefix );
switch (map_name( name, buf, pl, "/", ctx->delimiter )) { switch (map_name( name, -1, buf, pl, "/", ctx->delimiter )) {
case -1: case -1:
error( "IMAP error: mailbox name %s contains server's hierarchy delimiter\n", name ); error( "IMAP error: mailbox name %s contains server's hierarchy delimiter\n", name );
return -1; return -1;

2
src/main_sync.c

@ -527,7 +527,7 @@ store_listed( int sts, string_list_t *boxes, void *aux )
for (string_list_t *box = boxes; box; box = box->next) { for (string_list_t *box = boxes; box; box = box->next) {
if (mvars->ctx[t]->conf->flat_delim[0]) { 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, -1, (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 );
fail = 1; fail = 1;
} else { } else {

2
src/sync.c

@ -503,7 +503,7 @@ sync_boxes( store_t *ctx[], const char * const names[], int present[], channel_c
"INBOX" : names[t]; "INBOX" : names[t];
if (!ctx[t]->conf->flat_delim[0]) { 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], -1, &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] );
bail3: bail3:
svars->ret = SYNC_FAIL; svars->ret = SYNC_FAIL;

14
src/util.c

@ -531,19 +531,21 @@ cur_user( void )
/* Return value: 0 = ok, -1 = out found in arg, -2 = in found in arg but no out specified */ /* Return value: 0 = ok, -1 = out found in arg, -2 = in found in arg but no out specified */
int int
map_name( const char *arg, char **result, uint reserve, const char *in, const char *out ) map_name( const char *arg, int l, char **result, uint reserve, const char *in, const char *out )
{ {
char *p; char *p;
uint i, l, ll, num, inl, outl; int i, ll, num, inl, outl;
assert( arg ); assert( arg );
if (l < 0)
l = strlen( arg ); l = strlen( arg );
assert( in ); assert( in );
inl = strlen( in ); inl = strlen( in );
if (!inl) { 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 );
(*result)[reserve + l] = 0;
return 0; return 0;
} }
assert( out ); assert( out );
@ -551,6 +553,8 @@ map_name( const char *arg, char **result, uint reserve, const char *in, const ch
if (equals( in, (int)inl, out, outl )) if (equals( in, (int)inl, out, outl ))
goto copy; goto copy;
for (num = 0, i = 0; i < l; ) { for (num = 0, i = 0; i < l; ) {
if (i + inl > l)
goto fout;
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 fout; goto fout;
@ -559,6 +563,8 @@ map_name( const char *arg, char **result, uint reserve, const char *in, const ch
continue; continue;
fout: fout:
if (outl) { if (outl) {
if (i + outl > l)
goto fnexti;
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;
@ -574,6 +580,8 @@ map_name( const char *arg, char **result, uint reserve, const char *in, const ch
*result = nfmalloc( reserve + l + num * (outl - inl) + 1 ); *result = nfmalloc( reserve + l + num * (outl - inl) + 1 );
p = *result + reserve; p = *result + reserve;
for (i = 0; i < l; ) { for (i = 0; i < l; ) {
if (i + inl > l)
goto rnexti;
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;

Loading…
Cancel
Save