mirror of https://gitee.com/openkylin/qemu.git
block/rbd: Add an escape-aware strchr helper
Sometimes the parser needs to further split a token it has collected from the token input stream. Right now, it does a cursory check to see if the relevant characters appear in the token to determine if it should break it down further. However, qemu_rbd_next_tok() will escape characters as it removes tokens from the token stream and plain strchr() won't. This can make the initial strchr() check slightly misleading since it implies qemu_rbd_next_tok() will find the token and split on it, except the reality is that qemu_rbd_next_tok() will pass over it if it is escaped. Use a custom strchr to avoid mixing escaped and unescaped string operations. Furthermore, this code is identical to how qemu_rbd_next_tok() seeks its next token, so incorporate this custom strchr into the body of that function to reduce duplication. Reported-by: Han Han <hhan@redhat.com> Fixes: https://bugzilla.redhat.com/1873913 Signed-off-by: Connor Kuehl <ckuehl@redhat.com> Message-Id: <20210421212343.85524-3-ckuehl@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
f7afa7daa0
commit
2b99cfce08
32
block/rbd.c
32
block/rbd.c
|
@ -113,21 +113,31 @@ static int qemu_rbd_connect(rados_t *cluster, rados_ioctx_t *io_ctx,
|
|||
const char *keypairs, const char *secretid,
|
||||
Error **errp);
|
||||
|
||||
static char *qemu_rbd_strchr(char *src, char delim)
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p = src; *p; ++p) {
|
||||
if (*p == delim) {
|
||||
return p;
|
||||
}
|
||||
if (*p == '\\' && p[1] != '\0') {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *qemu_rbd_next_tok(char *src, char delim, char **p)
|
||||
{
|
||||
char *end;
|
||||
|
||||
*p = NULL;
|
||||
|
||||
for (end = src; *end; ++end) {
|
||||
if (*end == delim) {
|
||||
break;
|
||||
}
|
||||
if (*end == '\\' && end[1] != '\0') {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
if (*end == delim) {
|
||||
end = qemu_rbd_strchr(src, delim);
|
||||
if (end) {
|
||||
*p = end + 1;
|
||||
*end = '\0';
|
||||
}
|
||||
|
@ -171,7 +181,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
|
|||
qemu_rbd_unescape(found_str);
|
||||
qdict_put_str(options, "pool", found_str);
|
||||
|
||||
if (strchr(p, '@')) {
|
||||
if (qemu_rbd_strchr(p, '@')) {
|
||||
image_name = qemu_rbd_next_tok(p, '@', &p);
|
||||
|
||||
found_str = qemu_rbd_next_tok(p, ':', &p);
|
||||
|
@ -181,7 +191,7 @@ static void qemu_rbd_parse_filename(const char *filename, QDict *options,
|
|||
image_name = qemu_rbd_next_tok(p, ':', &p);
|
||||
}
|
||||
/* Check for namespace in the image_name */
|
||||
if (strchr(image_name, '/')) {
|
||||
if (qemu_rbd_strchr(image_name, '/')) {
|
||||
found_str = qemu_rbd_next_tok(image_name, '/', &image_name);
|
||||
qemu_rbd_unescape(found_str);
|
||||
qdict_put_str(options, "namespace", found_str);
|
||||
|
|
|
@ -55,6 +55,10 @@ _filter_conf()
|
|||
$QEMU_IMG info "json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=${BOGUS_CONF}'}" 2>&1 | _filter_conf
|
||||
$QEMU_IMG info "json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'${BOGUS_CONF}'}" 2>&1 | _filter_conf
|
||||
|
||||
# Regression test: the qemu-img invocation is expected to fail, but it should
|
||||
# not seg fault the parser.
|
||||
$QEMU_IMG create "rbd:rbd/aa\/bb:conf=${BOGUS_CONF}" 1M 2>&1 | _filter_conf
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
|
|
|
@ -4,4 +4,7 @@ unable to get monitor info from DNS SRV with service name: ceph-mon
|
|||
qemu-img: Could not open 'json:{'file.driver':'rbd','file.filename':'rbd:rbd/bogus:conf=BOGUS_CONF'}': error connecting: No such file or directory
|
||||
unable to get monitor info from DNS SRV with service name: ceph-mon
|
||||
qemu-img: Could not open 'json:{'file.driver':'rbd','file.pool':'rbd','file.image':'bogus','file.conf':'BOGUS_CONF'}': error connecting: No such file or directory
|
||||
Formatting 'rbd:rbd/aa\/bb:conf=BOGUS_CONF', fmt=raw size=1048576
|
||||
unable to get monitor info from DNS SRV with service name: ceph-mon
|
||||
qemu-img: rbd:rbd/aa\/bb:conf=BOGUS_CONF: error connecting: No such file or directory
|
||||
*** done
|
||||
|
|
Loading…
Reference in New Issue