* [PATCH for-8.2 0/2] qdev array property fixes @ 2023-11-21 17:34 Kevin Wolf 2023-11-21 17:34 ` [PATCH for-8.2 1/2] qdev: Fix crash in array property getter Kevin Wolf ` (3 more replies) 0 siblings, 4 replies; 11+ messages in thread From: Kevin Wolf @ 2023-11-21 17:34 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, thuth, armbru, philmd, peter.maydell Kevin Wolf (2): qdev: Fix crash in array property getter string-output-visitor: Support lists for non-integer types hw/core/qdev-properties.c | 33 ++++++++++++++++++++++++++------- qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- 2 files changed, 46 insertions(+), 11 deletions(-) -- 2.42.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH for-8.2 1/2] qdev: Fix crash in array property getter 2023-11-21 17:34 [PATCH for-8.2 0/2] qdev array property fixes Kevin Wolf @ 2023-11-21 17:34 ` Kevin Wolf 2023-11-24 18:06 ` Philippe Mathieu-Daudé 2023-11-21 17:34 ` [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types Kevin Wolf ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Kevin Wolf @ 2023-11-21 17:34 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, thuth, armbru, philmd, peter.maydell Passing an uninitialised list to visit_start_list() happens to work for the QObject output visitor because it treats the pointer as an opaque value and never dereferences it, but the string output visitor expects a valid list to check if it has more than one element. The existing code crashes with the string output visitor if the uninitialised value is non-NULL. Passing an explicit NULL would fix the crash, but still result in wrong output. Rework get_prop_array() so that it conforms to the expectations that the string output visitor has. This includes building a real list first and using visit_next_list() to iterate it. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1993 Reported-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- hw/core/qdev-properties.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 91632f7be9..840006e953 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -689,23 +689,36 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name, Property *prop = opaque; uint32_t *alenptr = object_field_prop_ptr(obj, prop); void **arrayptr = (void *)obj + prop->arrayoffset; - char *elem = *arrayptr; - GenericList *list; - const size_t list_elem_size = sizeof(*list) + prop->arrayfieldsize; + char *elemptr = *arrayptr; + ArrayElementList *list = NULL, *elem; + ArrayElementList **tail = &list; + const size_t size = sizeof(*list); int i; bool ok; - if (!visit_start_list(v, name, &list, list_elem_size, errp)) { + /* At least the string output visitor needs a real list */ + for (i = 0; i < *alenptr; i++) { + elem = g_new0(ArrayElementList, 1); + elem->value = elemptr; + elemptr += prop->arrayfieldsize; + + *tail = elem; + tail = &elem->next; + } + + if (!visit_start_list(v, name, (GenericList **) &list, size, errp)) { return; } - for (i = 0; i < *alenptr; i++) { - Property elem_prop = array_elem_prop(obj, prop, name, elem); + elem = list; + while (elem) { + Property elem_prop = array_elem_prop(obj, prop, name, elem->value); prop->arrayinfo->get(obj, v, NULL, &elem_prop, errp); if (*errp) { goto out_obj; } - elem += prop->arrayfieldsize; + elem = (ArrayElementList *) visit_next_list(v, (GenericList*) elem, + size); } /* visit_check_list() can only fail for input visitors */ @@ -714,6 +727,12 @@ static void get_prop_array(Object *obj, Visitor *v, const char *name, out_obj: visit_end_list(v, (void**) &list); + + while (list) { + elem = list; + list = elem->next; + g_free(elem); + } } static void default_prop_array(ObjectProperty *op, const Property *prop) -- 2.42.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 1/2] qdev: Fix crash in array property getter 2023-11-21 17:34 ` [PATCH for-8.2 1/2] qdev: Fix crash in array property getter Kevin Wolf @ 2023-11-24 18:06 ` Philippe Mathieu-Daudé 0 siblings, 0 replies; 11+ messages in thread From: Philippe Mathieu-Daudé @ 2023-11-24 18:06 UTC (permalink / raw) To: Kevin Wolf, qemu-devel; +Cc: thuth, armbru, peter.maydell, Dan Hoffman On 21/11/23 18:34, Kevin Wolf wrote: > Passing an uninitialised list to visit_start_list() happens to work for > the QObject output visitor because it treats the pointer as an opaque > value and never dereferences it, but the string output visitor expects a > valid list to check if it has more than one element. > > The existing code crashes with the string output visitor if the > uninitialised value is non-NULL. Passing an explicit NULL would fix the > crash, but still result in wrong output. > > Rework get_prop_array() so that it conforms to the expectations that the > string output visitor has. This includes building a real list first and > using visit_next_list() to iterate it. > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1993 > Reported-by: Thomas Huth <thuth@redhat.com> > Signed-off-by: Kevin Wolf <kwolf@redhat.com> > --- > hw/core/qdev-properties.c | 33 ++++++++++++++++++++++++++------- > 1 file changed, 26 insertions(+), 7 deletions(-) Per https://lore.kernel.org/qemu-devel/CAFXChKJ+OoxXH0Krvvc0-84VwTkat1CciOL=59+gyH+WYWEV_A@mail.gmail.com/ Tested-by: Dan Hoffman <dhoff749@gmail.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-21 17:34 [PATCH for-8.2 0/2] qdev array property fixes Kevin Wolf 2023-11-21 17:34 ` [PATCH for-8.2 1/2] qdev: Fix crash in array property getter Kevin Wolf @ 2023-11-21 17:34 ` Kevin Wolf 2023-11-30 13:11 ` Markus Armbruster 2023-11-21 18:48 ` [PATCH for-8.2 0/2] qdev array property fixes Thomas Huth 2023-11-28 16:23 ` Stefan Hajnoczi 3 siblings, 1 reply; 11+ messages in thread From: Kevin Wolf @ 2023-11-21 17:34 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, thuth, armbru, philmd, peter.maydell With the introduction of list-based array properties in qdev, the string output visitor has to deal with lists of non-integer elements now ('info qtree' prints all properties with the string output visitor). Currently there is no explicit support for such lists, and the resulting output is only the last element because string_output_set() always replaces the output with the latest value. Instead of replacing the old value, append comma separated values in list context. The difference can be observed in 'info qtree' with a 'rocker' device that has a 'ports' list with more than one element. Signed-off-by: Kevin Wolf <kwolf@redhat.com> --- qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c index 71ddc92b7b..c0cb72dbe4 100644 --- a/qapi/string-output-visitor.c +++ b/qapi/string-output-visitor.c @@ -74,11 +74,27 @@ static StringOutputVisitor *to_sov(Visitor *v) static void string_output_set(StringOutputVisitor *sov, char *string) { - if (sov->string) { - g_string_free(sov->string, true); + switch (sov->list_mode) { + case LM_STARTED: + sov->list_mode = LM_IN_PROGRESS; + /* fall through */ + case LM_NONE: + if (sov->string) { + g_string_free(sov->string, true); + } + sov->string = g_string_new(string); + g_free(string); + break; + + case LM_IN_PROGRESS: + case LM_END: + g_string_append(sov->string, ", "); + g_string_append(sov->string, string); + break; + + default: + abort(); } - sov->string = g_string_new(string); - g_free(string); } static void string_output_append(StringOutputVisitor *sov, int64_t a) -- 2.42.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-21 17:34 ` [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types Kevin Wolf @ 2023-11-30 13:11 ` Markus Armbruster 2023-11-30 13:21 ` Stefan Hajnoczi 2023-11-30 14:00 ` Kevin Wolf 0 siblings, 2 replies; 11+ messages in thread From: Markus Armbruster @ 2023-11-30 13:11 UTC (permalink / raw) To: Kevin Wolf; +Cc: qemu-devel, thuth, philmd, peter.maydell, Stefan Hajnoczi I understand Stefan already took this patch. I'm looking at it anyway, because experience has taught me to be very afraid of the string visitors. Kevin Wolf <kwolf@redhat.com> writes: > With the introduction of list-based array properties in qdev, the string > output visitor has to deal with lists of non-integer elements now ('info > qtree' prints all properties with the string output visitor). > > Currently there is no explicit support for such lists, and the resulting > output is only the last element because string_output_set() always > replaces the output with the latest value. Yes. The string visitors were created just for QOM's object_property_parse() and object_property_print(). At the time, QOM properties were limited to scalars, and the new visitors implemented just enough of the visitor API to be usable with scalars. This was a Really Bad Idea(tm). Commit a020f9809cf (qapi: add string-based visitors) and b2cd7dee86f (qom: add generic string parsing/printing). When we wanted a QOM property for "set of NUMA node number", we extended the visitors to support integer lists. With fancy range syntax. Except for 'size'. This was another Really Bad Idea(tm). Commit 659268ffbff (qapi: make string input visitor parse int list) and 69e255635d0 (qapi: make string output visitor parse int list) All the visitor stuff was scandalously under-documented (that's not even a bad idea, just a Really Bad Habit(tm)). When we added documentation much later, we missed the lack of support for lists with elements other than integers. We later fixed that oversight for the input visitor only. Commit adfb264c9ed (qapi: Document visitor interfaces, add assertions) and c9fba9de89d (qapi: Rewrite string-input-visitor's integer and list parsing) Your patch extends the string output visitor to support lists of arbitrary scalars. > Instead of replacing the old > value, append comma separated values in list context. > > The difference can be observed in 'info qtree' with a 'rocker' device > that has a 'ports' list with more than one element. > > Signed-off-by: Kevin Wolf <kwolf@redhat.com> > --- > qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- > 1 file changed, 20 insertions(+), 4 deletions(-) Missing: update of string-output-visitor.h's comment * The string output visitor does not implement support for visiting * QAPI structs, alternates, null, or arbitrary QTypes. It also * requires a non-null list argument to visit_start_list(). It is wrong before the patch: most lists do not work. After the patch, only lists of scalars work. Document that, please. Maybe: * The string output visitor does not implement support for visiting * QAPI structs, alternates, null, or arbitrary QTypes. Only flat lists * are supported. It also requires a non-null list argument to * visit_start_list(). Stolen from string-input-visitor.h's comment. Could instead use "Only lists of scalars are supported." Follow-up patch would be fine. > > diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c > index 71ddc92b7b..c0cb72dbe4 100644 > --- a/qapi/string-output-visitor.c > +++ b/qapi/string-output-visitor.c > @@ -74,11 +74,27 @@ static StringOutputVisitor *to_sov(Visitor *v) > > static void string_output_set(StringOutputVisitor *sov, char *string) > { > - if (sov->string) { > - g_string_free(sov->string, true); > + switch (sov->list_mode) { > + case LM_STARTED: > + sov->list_mode = LM_IN_PROGRESS; > + /* fall through */ > + case LM_NONE: > + if (sov->string) { > + g_string_free(sov->string, true); > + } > + sov->string = g_string_new(string); > + g_free(string); > + break; > + > + case LM_IN_PROGRESS: > + case LM_END: > + g_string_append(sov->string, ", "); > + g_string_append(sov->string, string); > + break; > + > + default: > + abort(); > } > - sov->string = g_string_new(string); > - g_free(string); > } > > static void string_output_append(StringOutputVisitor *sov, int64_t a) The ->list_mode state machine was designed for parsing integer lists with fancy range syntax. Let me try to figure out how it works. Initial state is LM_NONE. On start_list(): LM_NONE -> LM_STARTED. On end_list(): any -> LM_NONE. On next_list(): any -> LM_END. On print_type_int64(): LM_STARTED -> LM_IN_PROGRESS LM_IN_PROGRESS -> LM_IN_PROGRESS LM_END -> LM_END The two states LM_SIGNED_INTERVAL and LM_UNSIGNED_INTERVAL have never been used. Copy-pasta from opts-visitor.c. Only real walks call next_list(), virtual walks do not. In a real walk, print_type_int64() executes its LM_END case for non-first elements. In a virtual walk, it executes its LM_IN_PROGRESS case. This can't be right. What a load of confused crap. Your string_output_set() treats LM_IN_PROGRESS and LM_END the same. This could be right ;) It behaves as before in state LM_NONE: overwrite sov->string. Good. In state LM_STARTED, it overwrites sov->string. Good. In states, LM_IN_PROGRESS and LM_END, it appends to sov->string. Good. It is used for all scalar visitors except print_type_int64() and print_type_uint64(). Therefore, it makes all remaining scalars work in lists. Good. Objects and nested lists still don't work. If "info qdev" runs into a such a property, it'll crash. Not your patch's fault. I loathe the string visitors. Reviewed-by: Markus Armbruster <armbru@redhat.com> But please take care of fixing the comment in string-output-visitor.h. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-30 13:11 ` Markus Armbruster @ 2023-11-30 13:21 ` Stefan Hajnoczi 2023-11-30 13:41 ` Markus Armbruster 2023-11-30 14:00 ` Kevin Wolf 1 sibling, 1 reply; 11+ messages in thread From: Stefan Hajnoczi @ 2023-11-30 13:21 UTC (permalink / raw) To: Markus Armbruster Cc: Kevin Wolf, qemu-devel, thuth, philmd, peter.maydell, Stefan Hajnoczi On Thu, 30 Nov 2023 at 08:12, Markus Armbruster <armbru@redhat.com> wrote: > > I understand Stefan already took this patch. I'm looking at it anyway, > because experience has taught me to be very afraid of the string > visitors. Hi Markus, I should have waited for your review. Sorry! Stefan ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-30 13:21 ` Stefan Hajnoczi @ 2023-11-30 13:41 ` Markus Armbruster 0 siblings, 0 replies; 11+ messages in thread From: Markus Armbruster @ 2023-11-30 13:41 UTC (permalink / raw) To: Stefan Hajnoczi Cc: Kevin Wolf, qemu-devel, thuth, philmd, peter.maydell, Stefan Hajnoczi Stefan Hajnoczi <stefanha@gmail.com> writes: > On Thu, 30 Nov 2023 at 08:12, Markus Armbruster <armbru@redhat.com> wrote: >> >> I understand Stefan already took this patch. I'm looking at it anyway, >> because experience has taught me to be very afraid of the string >> visitors. > > Hi Markus, > I should have waited for your review. Sorry! No reason to be sorry! It's a regression, and we're at rc2 already. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-30 13:11 ` Markus Armbruster 2023-11-30 13:21 ` Stefan Hajnoczi @ 2023-11-30 14:00 ` Kevin Wolf 2023-11-30 14:35 ` Markus Armbruster 1 sibling, 1 reply; 11+ messages in thread From: Kevin Wolf @ 2023-11-30 14:00 UTC (permalink / raw) To: Markus Armbruster Cc: qemu-devel, thuth, philmd, peter.maydell, Stefan Hajnoczi Am 30.11.2023 um 14:11 hat Markus Armbruster geschrieben: > I understand Stefan already took this patch. I'm looking at it anyway, > because experience has taught me to be very afraid of the string > visitors. > > Kevin Wolf <kwolf@redhat.com> writes: > > > With the introduction of list-based array properties in qdev, the string > > output visitor has to deal with lists of non-integer elements now ('info > > qtree' prints all properties with the string output visitor). > > > > Currently there is no explicit support for such lists, and the resulting > > output is only the last element because string_output_set() always > > replaces the output with the latest value. > > Yes. > > The string visitors were created just for QOM's object_property_parse() > and object_property_print(). At the time, QOM properties were limited > to scalars, and the new visitors implemented just enough of the visitor > API to be usable with scalars. This was a Really Bad Idea(tm). > > Commit a020f9809cf (qapi: add string-based visitors) > and b2cd7dee86f (qom: add generic string parsing/printing). > > When we wanted a QOM property for "set of NUMA node number", we extended > the visitors to support integer lists. With fancy range syntax. Except > for 'size'. This was another Really Bad Idea(tm). > > Commit 659268ffbff (qapi: make string input visitor parse int list) > and 69e255635d0 (qapi: make string output visitor parse int list) > > All the visitor stuff was scandalously under-documented (that's not even > a bad idea, just a Really Bad Habit(tm)). When we added documentation > much later, we missed the lack of support for lists with elements other > than integers. We later fixed that oversight for the input visitor > only. > > Commit adfb264c9ed (qapi: Document visitor interfaces, add assertions) > and c9fba9de89d (qapi: Rewrite string-input-visitor's integer and list parsing) > > Your patch extends the string output visitor to support lists of > arbitrary scalars. > > > Instead of replacing the old > > value, append comma separated values in list context. > > > > The difference can be observed in 'info qtree' with a 'rocker' device > > that has a 'ports' list with more than one element. > > > > Signed-off-by: Kevin Wolf <kwolf@redhat.com> > > --- > > qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- > > 1 file changed, 20 insertions(+), 4 deletions(-) > > Missing: update of string-output-visitor.h's comment > > * The string output visitor does not implement support for visiting > * QAPI structs, alternates, null, or arbitrary QTypes. It also > * requires a non-null list argument to visit_start_list(). > > It is wrong before the patch: most lists do not work. After the patch, > only lists of scalars work. Document that, please. Maybe: > > * The string output visitor does not implement support for visiting > * QAPI structs, alternates, null, or arbitrary QTypes. Only flat lists > * are supported. It also requires a non-null list argument to > * visit_start_list(). > > Stolen from string-input-visitor.h's comment. > > Could instead use "Only lists of scalars are supported." > > Follow-up patch would be fine. I guess I'm lucky that the comment I missed already failed to point out the limitations before, so at least I didn't make anything worse! Adding a sentence makes sense to me. I find "list of scalars" easier to understand than "flat lists" (in particular, I would have considered a list of structs to be flat), so I'd prefer that wording. > > > > diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c > > index 71ddc92b7b..c0cb72dbe4 100644 > > --- a/qapi/string-output-visitor.c > > +++ b/qapi/string-output-visitor.c > > @@ -74,11 +74,27 @@ static StringOutputVisitor *to_sov(Visitor *v) > > > > static void string_output_set(StringOutputVisitor *sov, char *string) > > { > > - if (sov->string) { > > - g_string_free(sov->string, true); > > + switch (sov->list_mode) { > > + case LM_STARTED: > > + sov->list_mode = LM_IN_PROGRESS; > > + /* fall through */ > > + case LM_NONE: > > + if (sov->string) { > > + g_string_free(sov->string, true); > > + } > > + sov->string = g_string_new(string); > > + g_free(string); > > + break; > > + > > + case LM_IN_PROGRESS: > > + case LM_END: > > + g_string_append(sov->string, ", "); > > + g_string_append(sov->string, string); > > + break; > > + > > + default: > > + abort(); > > } > > - sov->string = g_string_new(string); > > - g_free(string); > > } > > > > static void string_output_append(StringOutputVisitor *sov, int64_t a) > > The ->list_mode state machine was designed for parsing integer lists > with fancy range syntax. Let me try to figure out how it works. > > Initial state is LM_NONE. > > On start_list(): > LM_NONE -> LM_STARTED. > > On end_list(): > any -> LM_NONE. > > On next_list(): > any -> LM_END. > > On print_type_int64(): > LM_STARTED -> LM_IN_PROGRESS > LM_IN_PROGRESS -> LM_IN_PROGRESS > LM_END -> LM_END > > The two states LM_SIGNED_INTERVAL and LM_UNSIGNED_INTERVAL have never > been used. Copy-pasta from opts-visitor.c. > > Only real walks call next_list(), virtual walks do not. In a real walk, > print_type_int64() executes its LM_END case for non-first elements. In > a virtual walk, it executes its LM_IN_PROGRESS case. This can't be > right. > > What a load of confused crap. I won't try to argue that the string visitor isn't a load of confused crap, but I don't see how LM_END is non-first elements? It only gets set in next_list() for the last element. The more interesting point I wasn't aware of is that virtual walks don't need to call next_list(). If we can fix the string visitor, doing a virtual walk might have made more sense for the array property getter than construction a temporary real list? Or can't you mix virtual and real with the same visitor? Because I assume the callers of property getters are doing a real walk. Kevin ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types 2023-11-30 14:00 ` Kevin Wolf @ 2023-11-30 14:35 ` Markus Armbruster 0 siblings, 0 replies; 11+ messages in thread From: Markus Armbruster @ 2023-11-30 14:35 UTC (permalink / raw) To: Kevin Wolf; +Cc: qemu-devel, thuth, philmd, peter.maydell, Stefan Hajnoczi Kevin Wolf <kwolf@redhat.com> writes: > Am 30.11.2023 um 14:11 hat Markus Armbruster geschrieben: >> I understand Stefan already took this patch. I'm looking at it anyway, >> because experience has taught me to be very afraid of the string >> visitors. >> >> Kevin Wolf <kwolf@redhat.com> writes: >> >> > With the introduction of list-based array properties in qdev, the string >> > output visitor has to deal with lists of non-integer elements now ('info >> > qtree' prints all properties with the string output visitor). >> > >> > Currently there is no explicit support for such lists, and the resulting >> > output is only the last element because string_output_set() always >> > replaces the output with the latest value. >> >> Yes. >> >> The string visitors were created just for QOM's object_property_parse() >> and object_property_print(). At the time, QOM properties were limited >> to scalars, and the new visitors implemented just enough of the visitor >> API to be usable with scalars. This was a Really Bad Idea(tm). >> >> Commit a020f9809cf (qapi: add string-based visitors) >> and b2cd7dee86f (qom: add generic string parsing/printing). >> >> When we wanted a QOM property for "set of NUMA node number", we extended >> the visitors to support integer lists. With fancy range syntax. Except >> for 'size'. This was another Really Bad Idea(tm). >> >> Commit 659268ffbff (qapi: make string input visitor parse int list) >> and 69e255635d0 (qapi: make string output visitor parse int list) >> >> All the visitor stuff was scandalously under-documented (that's not even >> a bad idea, just a Really Bad Habit(tm)). When we added documentation >> much later, we missed the lack of support for lists with elements other >> than integers. We later fixed that oversight for the input visitor >> only. >> >> Commit adfb264c9ed (qapi: Document visitor interfaces, add assertions) >> and c9fba9de89d (qapi: Rewrite string-input-visitor's integer and list parsing) >> >> Your patch extends the string output visitor to support lists of >> arbitrary scalars. >> >> > Instead of replacing the old >> > value, append comma separated values in list context. >> > >> > The difference can be observed in 'info qtree' with a 'rocker' device >> > that has a 'ports' list with more than one element. >> > >> > Signed-off-by: Kevin Wolf <kwolf@redhat.com> >> > --- >> > qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- >> > 1 file changed, 20 insertions(+), 4 deletions(-) >> >> Missing: update of string-output-visitor.h's comment >> >> * The string output visitor does not implement support for visiting >> * QAPI structs, alternates, null, or arbitrary QTypes. It also >> * requires a non-null list argument to visit_start_list(). >> >> It is wrong before the patch: most lists do not work. After the patch, >> only lists of scalars work. Document that, please. Maybe: >> >> * The string output visitor does not implement support for visiting >> * QAPI structs, alternates, null, or arbitrary QTypes. Only flat lists >> * are supported. It also requires a non-null list argument to >> * visit_start_list(). >> >> Stolen from string-input-visitor.h's comment. >> >> Could instead use "Only lists of scalars are supported." >> >> Follow-up patch would be fine. > > I guess I'm lucky that the comment I missed already failed to point out > the limitations before, so at least I didn't make anything worse! Right! > Adding a sentence makes sense to me. I find "list of scalars" easier to > understand than "flat lists" (in particular, I would have considered a > list of structs to be flat), so I'd prefer that wording. Agree. >> > >> > diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c >> > index 71ddc92b7b..c0cb72dbe4 100644 >> > --- a/qapi/string-output-visitor.c >> > +++ b/qapi/string-output-visitor.c >> > @@ -74,11 +74,27 @@ static StringOutputVisitor *to_sov(Visitor *v) >> > >> > static void string_output_set(StringOutputVisitor *sov, char *string) >> > { >> > - if (sov->string) { >> > - g_string_free(sov->string, true); >> > + switch (sov->list_mode) { >> > + case LM_STARTED: >> > + sov->list_mode = LM_IN_PROGRESS; >> > + /* fall through */ >> > + case LM_NONE: >> > + if (sov->string) { >> > + g_string_free(sov->string, true); >> > + } >> > + sov->string = g_string_new(string); >> > + g_free(string); >> > + break; >> > + >> > + case LM_IN_PROGRESS: >> > + case LM_END: >> > + g_string_append(sov->string, ", "); >> > + g_string_append(sov->string, string); >> > + break; >> > + >> > + default: >> > + abort(); >> > } >> > - sov->string = g_string_new(string); >> > - g_free(string); >> > } >> > >> > static void string_output_append(StringOutputVisitor *sov, int64_t a) >> >> The ->list_mode state machine was designed for parsing integer lists >> with fancy range syntax. Let me try to figure out how it works. >> >> Initial state is LM_NONE. >> >> On start_list(): >> LM_NONE -> LM_STARTED. >> >> On end_list(): >> any -> LM_NONE. >> >> On next_list(): >> any -> LM_END. >> >> On print_type_int64(): >> LM_STARTED -> LM_IN_PROGRESS >> LM_IN_PROGRESS -> LM_IN_PROGRESS >> LM_END -> LM_END >> >> The two states LM_SIGNED_INTERVAL and LM_UNSIGNED_INTERVAL have never >> been used. Copy-pasta from opts-visitor.c. >> >> Only real walks call next_list(), virtual walks do not. In a real walk, >> print_type_int64() executes its LM_END case for non-first elements. In >> a virtual walk, it executes its LM_IN_PROGRESS case. This can't be >> right. >> >> What a load of confused crap. > > I won't try to argue that the string visitor isn't a load of confused > crap, but I don't see how LM_END is non-first elements? It only gets set > in next_list() for the last element. You're right; I missed that. > The more interesting point I wasn't aware of is that virtual walks don't > need to call next_list(). visitor.h: * After visit_start_list() succeeds, the caller may visit its members * one after the other. A real visit (where @list is non-NULL) uses * visit_next_list() for traversing the linked list, while a virtual * visit (where @list is NULL) uses other means. For each list * element, call the appropriate visit_type_FOO() with name set to * NULL and obj set to the address of the value member of the list * element. Finally, visit_end_list() needs to be called with the * same @list to clean up, even if intermediate visits fail. See the * examples above. > If we can fix the string visitor, doing a > virtual walk might have made more sense for the array property getter > than construction a temporary real list? > > Or can't you mix virtual and real with the same visitor? Because I > assume the callers of property getters are doing a real walk. visitor.h: * A visitor should be used for exactly one top-level visit_type_FOO() * or virtual walk; if that is successful, the caller can optionally * call visit_complete() (useful only for output visits, but safe to * call on all visits). Then, regardless of success or failure, the * user should call visit_free() to clean up resources. It is okay to * free the visitor without completing the visit, if some other error * is detected in the meantime. The callers of property getters I can see look more or less like this: v = FOO_output_visitor_new(..., &ret); if (object_property_get(obj, name, v, errp)) { visit_complete(v, &ret); } visit_free(v); Such callers don't walk anything themselves. I think a virtual walk should be okay. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 0/2] qdev array property fixes 2023-11-21 17:34 [PATCH for-8.2 0/2] qdev array property fixes Kevin Wolf 2023-11-21 17:34 ` [PATCH for-8.2 1/2] qdev: Fix crash in array property getter Kevin Wolf 2023-11-21 17:34 ` [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types Kevin Wolf @ 2023-11-21 18:48 ` Thomas Huth 2023-11-28 16:23 ` Stefan Hajnoczi 3 siblings, 0 replies; 11+ messages in thread From: Thomas Huth @ 2023-11-21 18:48 UTC (permalink / raw) To: Kevin Wolf, qemu-devel; +Cc: armbru, philmd, peter.maydell On 21/11/2023 18.34, Kevin Wolf wrote: > Kevin Wolf (2): > qdev: Fix crash in array property getter > string-output-visitor: Support lists for non-integer types > > hw/core/qdev-properties.c | 33 ++++++++++++++++++++++++++------- > qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- > 2 files changed, 46 insertions(+), 11 deletions(-) Thanks, I can confirm that this series fixes the problem for me - both locally when compiling with CFI, and on Travis (where I observed the problem first): https://app.travis-ci.com/github/huth/qemu/jobs/613659935#L6580 Tested-by: Thomas Huth <thuth@redhat.com> ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH for-8.2 0/2] qdev array property fixes 2023-11-21 17:34 [PATCH for-8.2 0/2] qdev array property fixes Kevin Wolf ` (2 preceding siblings ...) 2023-11-21 18:48 ` [PATCH for-8.2 0/2] qdev array property fixes Thomas Huth @ 2023-11-28 16:23 ` Stefan Hajnoczi 3 siblings, 0 replies; 11+ messages in thread From: Stefan Hajnoczi @ 2023-11-28 16:23 UTC (permalink / raw) To: Kevin Wolf; +Cc: qemu-devel, thuth, armbru, philmd, peter.maydell On Tue, 21 Nov 2023 at 12:35, Kevin Wolf <kwolf@redhat.com> wrote: > > Kevin Wolf (2): > qdev: Fix crash in array property getter > string-output-visitor: Support lists for non-integer types > > hw/core/qdev-properties.c | 33 ++++++++++++++++++++++++++------- > qapi/string-output-visitor.c | 24 ++++++++++++++++++++---- > 2 files changed, 46 insertions(+), 11 deletions(-) Applied, thanks! Stefan > > -- > 2.42.0 > > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2023-11-30 14:37 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-11-21 17:34 [PATCH for-8.2 0/2] qdev array property fixes Kevin Wolf 2023-11-21 17:34 ` [PATCH for-8.2 1/2] qdev: Fix crash in array property getter Kevin Wolf 2023-11-24 18:06 ` Philippe Mathieu-Daudé 2023-11-21 17:34 ` [PATCH for-8.2 2/2] string-output-visitor: Support lists for non-integer types Kevin Wolf 2023-11-30 13:11 ` Markus Armbruster 2023-11-30 13:21 ` Stefan Hajnoczi 2023-11-30 13:41 ` Markus Armbruster 2023-11-30 14:00 ` Kevin Wolf 2023-11-30 14:35 ` Markus Armbruster 2023-11-21 18:48 ` [PATCH for-8.2 0/2] qdev array property fixes Thomas Huth 2023-11-28 16:23 ` Stefan Hajnoczi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).