clients: return NULL array on auto-completion failure

readline crashes if we return an empty completion list; return NULL
instead.

This is reproducible, for example, with:

 $ nmcli --ask connection add
 Interface name [*]: doesnotexist<TAB>
 Segmentation fault (core dumped)

 $ nmcli --ask connection add
 Interface name [*]:
 Connection type: avian-carr<TAB>
 Segmentation fault (core dumped)
This commit is contained in:
Beniamino Galvani 2017-06-21 14:18:24 +02:00
parent a84facb90c
commit afac7621ae
2 changed files with 29 additions and 8 deletions

View file

@ -294,13 +294,18 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info,
if (*out_to_free) { if (*out_to_free) {
char **v = *out_to_free; char **v = *out_to_free;
for (i =0, j = 0; v[i]; i++) { for (i = 0, j = 0; v[i]; i++) {
if (strncmp (v[i], text, text_len) != 0) if (strncmp (v[i], text, text_len) != 0)
continue; continue;
v[j++] = v[i]; v[j++] = v[i];
} }
v[j++] = NULL; if (j)
return (const char *const*) *out_to_free; v[j++] = NULL;
else {
g_free (v);
v = NULL;
}
return (const char *const*) v;
} else { } else {
const char *const*v = values; const char *const*v = values;
char **r; char **r;
@ -312,6 +317,8 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info,
} }
if (j == i) if (j == i)
return values; return values;
else if (!j)
return NULL;
r = g_new (char *, j + 1); r = g_new (char *, j + 1);
v = values; v = values;

View file

@ -1759,7 +1759,12 @@ _complete_fcn_vpn_service_type (ARGS_COMPLETE_FCN)
values[j] = values[i]; values[j] = values[i];
j++; j++;
} }
values[j++] = NULL; if (j)
values[j++] = NULL;
else {
g_free (values);
values = NULL;
}
} }
return (const char *const*) (*out_to_free = values); return (const char *const*) (*out_to_free = values);
} }
@ -2378,7 +2383,12 @@ _complete_fcn_connection_type (ARGS_COMPLETE_FCN)
result[j++] = g_strdup (v); result[j++] = g_strdup (v);
} }
} }
result[j++] = NULL; if (j)
result[j++] = NULL;
else {
g_free (result);
result = NULL;
}
return (const char *const*) (*out_to_free = result); return (const char *const*) (*out_to_free = result);
} }
@ -2526,10 +2536,14 @@ _complete_fcn_connection_master (ARGS_COMPLETE_FCN)
if (v && (!text || strncmp (text, v, text_len) == 0)) if (v && (!text || strncmp (text, v, text_len) == 0))
result[j++] = g_strdup (v); result[j++] = g_strdup (v);
} }
result[j++] = NULL; if (j)
result[j++] = NULL;
else {
g_free (result);
result = NULL;
}
*out_to_free = NULL; return (const char *const*) (*out_to_free = result);
return (const char *const*) result;
} }
static gboolean static gboolean