From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: Markus Armbruster <armbru@redhat.com>
Cc: P J P <ppandit@redhat.com>, Michael Tokarev <mjt@tls.msk.ru>,
qemu-devel@nongnu.org, Ling Liu <liuling-it@360.cn>
Subject: Re: [Qemu-devel] [PATCH] hmp: avoid redundant null termination of buffer
Date: Mon, 18 Jan 2016 14:38:19 +0100 [thread overview]
Message-ID: <20160118133819.GA29453@olga> (raw)
In-Reply-To: <87io2rnir4.fsf@blackfin.pond.sub.org>
On Mon, Jan 18, 2016 at 02:02:07PM +0100, Markus Armbruster wrote:
> Wolfgang Bumiller <w.bumiller@proxmox.com> writes:
>
> > On Tue, Jan 12, 2016 at 05:52:38PM +0100, Markus Armbruster wrote:
> >> Wolfgang Bumiller <w.bumiller@proxmox.com> writes:
> >>
> > while (1) {
> > separator = strchr(keys, '-');
> > keyname_len = separator ? separator - keys : strlen(keys);
>
> Preexisting: I wonder why the compiler doesn't warn here: separator -
> keys is ptrdiff_t, strlen() is size_t, and the left hand side is int.
I noticed and agree it should warn. We know that separator > keys (ie
positive), but we also use keyname_len as a '.*' parameter to printf()
which expects it to be an 'int', so when changing it to size_t we need
to cast it there. Would have to pass a pretty long key name for this to
be an issue... can this happen over any sane interface that doesn't
already give you the power to just 'kill -9 $qemu'?
> > - pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
> >
> > /* Be compatible with old interface, convert user inputted "<" */
> > - if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
> > - pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
> > + if (!strncmp(keys, "<", 1) && keyname_len == 1) {
>
> This strncmp() is a rather roundabout way to say keys[0] == '<'. I
> guess I'd dumb it down while touching it. Your choice.
Yes, but with the previous pstrcpy() of "less" etc. I thought this was a
style thing (and the compiler optimizes it out anyway last time I
checked).
> > + keys = "less";
>
> Works because we're resetting keys to point into the argument string at
> the end of the loop.
>
> > keyname_len = 4;
> > }
> > - keyname_buf[keyname_len] = 0;
> >
> > keylist = g_malloc0(sizeof(*keylist));
> > keylist->value = g_malloc0(sizeof(*keylist->value));
> > @@ -1769,16 +1766,16 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
> > }
> > tmp = keylist;
> >
> > - if (strstart(keyname_buf, "0x", NULL)) {
> > + if (strstart(keys, "0x", NULL)) {
> > char *endp;
> > - int value = strtoul(keyname_buf, &endp, 0);
> > - if (*endp != '\0') {
> > + int value = strtoul(keys, &endp, 0);
> > + if (*endp != '\0' && *endp != '-') {
>
> strtoul() will not parse beyond keyname_len, because it'll only accept
> hex digits after 0x, thus the '-' or 0 at keyname_len will make it stop.
>
> I guess I'd throw in assert(endp <= keys + keyname_len), and test
> endp != keys + keyname_len. What do you think?
Makes sense, but I doubt it'll ever be hit with sane strtoul()
implementations, but an assetion can't be harmful here either :-)
> > goto err_out;
> > }
> > keylist->value->type = KEY_VALUE_KIND_NUMBER;
> > keylist->value->u.number = value;
> > } else {
> > - int idx = index_from_key(keyname_buf);
> > + int idx = index_from_key(keys, keyname_len);
> > if (idx == Q_KEY_CODE__MAX) {
> > goto err_out;
> > }
> > @@ -1800,7 +1797,7 @@ out:
> > return;
> >
> > err_out:
> > - monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
> > + monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
> > goto out;
> > }
> >
> > diff --git a/include/ui/console.h b/include/ui/console.h
> > index adac36d..116bc2b 100644
> > --- a/include/ui/console.h
> > +++ b/include/ui/console.h
> > @@ -448,7 +448,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
> > void curses_display_init(DisplayState *ds, int full_screen);
> >
> > /* input.c */
> > -int index_from_key(const char *key);
> > +int index_from_key(const char *key, size_t key_length);
> >
> > /* gtk.c */
> > void early_gtk_display_init(int opengl);
> > diff --git a/ui/input-legacy.c b/ui/input-legacy.c
> > index 35dfc27..3454055 100644
> > --- a/ui/input-legacy.c
> > +++ b/ui/input-legacy.c
> > @@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
> > static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
> > QTAILQ_HEAD_INITIALIZER(led_handlers);
> >
> > -int index_from_key(const char *key)
> > +int index_from_key(const char *key, size_t key_length)
> > {
> > int i;
> >
> > for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
> > - if (!strcmp(key, QKeyCode_lookup[i])) {
> > + if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
> > + !QKeyCode_lookup[i][key_length]) {
> > break;
> > }
> > }
>
> Could !strncmp(key, QKeyCode_lookup[i], key_length + 1), but that's
> probably overly clever.
That's assuming the key name ends with a \0, which is not the case
coming from a combined key combination where key points to "ctrl-alt-f1"
and should find "ctrl".
> Overall, this is more subtle than a simple g_strndup() solution. But it
> doesn't quite reach the threshold for me asking you to redo it
> differently.
>
> I can work in the two changes I proposed on commit, if you like them:
> dumb down the test for "<", and add the assertion.
Sounds good.
next prev parent reply other threads:[~2016-01-18 13:39 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-17 12:40 [Qemu-devel] [PATCH] hmp: avoid redundant null termination of buffer P J P
2015-12-18 3:46 ` 刘令
2015-12-18 4:34 ` P J P
2015-12-22 18:48 ` Luiz Capitulino
2016-01-12 8:41 ` Markus Armbruster
2016-01-08 9:19 ` Wolfgang Bumiller
2016-01-08 12:19 ` P J P
2016-01-08 13:02 ` Wolfgang Bumiller
2016-01-08 13:59 ` P J P
2016-01-08 14:38 ` Wolfgang Bumiller
2016-01-08 17:32 ` P J P
2016-01-09 9:31 ` Wolfgang Bumiller
2016-01-09 13:03 ` P J P
2016-01-10 7:56 ` Michael Tokarev
2016-01-11 7:00 ` P J P
2016-01-11 7:59 ` Wolfgang Bumiller
2016-01-11 8:22 ` P J P
2016-01-12 8:45 ` Markus Armbruster
2016-01-12 9:27 ` Wolfgang Bumiller
2016-01-12 16:00 ` Markus Armbruster
2016-01-12 16:25 ` Wolfgang Bumiller
2016-01-12 16:52 ` Markus Armbruster
2016-01-13 8:09 ` Wolfgang Bumiller
2016-01-18 13:02 ` Markus Armbruster
2016-01-18 13:38 ` Wolfgang Bumiller [this message]
2016-01-18 14:23 ` Markus Armbruster
2016-01-26 9:36 ` Michael Tokarev
2016-01-28 10:52 ` Michael Tokarev
2016-01-28 14:45 ` Markus Armbruster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160118133819.GA29453@olga \
--to=w.bumiller@proxmox.com \
--cc=armbru@redhat.com \
--cc=liuling-it@360.cn \
--cc=mjt@tls.msk.ru \
--cc=ppandit@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.