add input length argument to map_name()

... and use it when parsing IMAP LIST responses.
This commit is contained in:
Oswald Buddenhagen 2021-11-26 22:58:16 +01:00
parent 5243c69863
commit bc3145617a
5 changed files with 18 additions and 10 deletions

View File

@ -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 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 );

View File

@ -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 */
return LIST_OK;
if (map_name( arg, (char **)&narg, offsetof(string_list_t, string), ctx->delimiter, "/") < 0) {
warn( "IMAP warning: ignoring mailbox %s (reserved character '/' in name)\n", arg );
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", argl, arg );
return LIST_OK;
}
// 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 );
switch (map_name( name, buf, pl, "/", ctx->delimiter )) {
switch (map_name( name, -1, buf, pl, "/", ctx->delimiter )) {
case -1:
error( "IMAP error: mailbox name %s contains server's hierarchy delimiter\n", name );
return -1;

View File

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

View File

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

View File

@ -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 */
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;
uint i, l, ll, num, inl, outl;
int i, ll, num, inl, outl;
assert( arg );
if (l < 0)
l = strlen( arg );
assert( in );
inl = strlen( in );
if (!inl) {
copy:
*result = nfmalloc( reserve + l + 1 );
memcpy( *result + reserve, arg, l + 1 );
memcpy( *result + reserve, arg, l );
(*result)[reserve + l] = 0;
return 0;
}
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 ))
goto copy;
for (num = 0, i = 0; i < l; ) {
if (i + inl > l)
goto fout;
for (ll = 0; ll < inl; ll++)
if (arg[i + ll] != in[ll])
goto fout;
@ -559,6 +563,8 @@ map_name( const char *arg, char **result, uint reserve, const char *in, const ch
continue;
fout:
if (outl) {
if (i + outl > l)
goto fnexti;
for (ll = 0; ll < outl; ll++)
if (arg[i + ll] != out[ll])
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 );
p = *result + reserve;
for (i = 0; i < l; ) {
if (i + inl > l)
goto rnexti;
for (ll = 0; ll < inl; ll++)
if (arg[i + ll] != in[ll])
goto rnexti;