Skip to content
  • Eric Blake's avatar
    ed841535
    qapi-commands: Wrap argument visit in visit_start_struct · ed841535
    Eric Blake authored
    
    
    The qmp-input visitor was allowing callers to play rather fast
    and loose: when visiting a QDict, you could grab members of the
    root dictionary without first pushing into the dict; among the
    culprit callers was the generated marshal code on the 'arguments'
    dictionary of a QMP command.  But we are about to tighten the
    input visitor, at which point the generated marshal code MUST
    follow the same paradigms as everyone else, of pushing into the
    struct before grabbing its keys.
    
    Generated code grows as follows:
    
    |@@ -515,7 +641,12 @@ void qmp_marshal_blockdev_backup(QDict *
    |     BlockdevBackup arg = {0};
    |
    |     v = qmp_input_get_visitor(qiv);
    |+    visit_start_struct(v, NULL, NULL, 0, &err);
    |+    if (err) {
    |+        goto out;
    |+    }
    |     visit_type_BlockdevBackup_members(v, &arg, &err);
    |+    visit_end_struct(v, err ? NULL : &err);
    |     if (err) {
    |         goto out;
    |     }
    |@@ -527,7 +715,9 @@ out:
    |     qmp_input_visitor_cleanup(qiv);
    |     qdv = qapi_dealloc_visitor_new();
    |     v = qapi_dealloc_get_visitor(qdv);
    |+    visit_start_struct(v, NULL, NULL, 0, NULL);
    |     visit_type_BlockdevBackup_members(v, &arg, NULL);
    |+    visit_end_struct(v, NULL);
    |     qapi_dealloc_visitor_cleanup(qdv);
    | }
    
    The use of 'err ? NULL : &err' is temporary; a later patch will
    clean that up when it splits visit_end_struct().
    
    Prior to this patch, the fact that there was no final
    visit_end_struct() meant that even though we are using a strict
    input visit, the marshalling code was not detecting excess input
    at the top level (only in nested levels).  Fortunately, we have
    code in monitor.c:qmp_check_client_args() that also checks for
    no excess arguments at the top level.  But as the generated code
    is more compact than the manual check, a later patch will clean
    up monitor.c to drop the redundancy added here.
    
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <1461879932-9020-9-git-send-email-eblake@redhat.com>
    Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
    ed841535
    qapi-commands: Wrap argument visit in visit_start_struct
    Eric Blake authored
    
    
    The qmp-input visitor was allowing callers to play rather fast
    and loose: when visiting a QDict, you could grab members of the
    root dictionary without first pushing into the dict; among the
    culprit callers was the generated marshal code on the 'arguments'
    dictionary of a QMP command.  But we are about to tighten the
    input visitor, at which point the generated marshal code MUST
    follow the same paradigms as everyone else, of pushing into the
    struct before grabbing its keys.
    
    Generated code grows as follows:
    
    |@@ -515,7 +641,12 @@ void qmp_marshal_blockdev_backup(QDict *
    |     BlockdevBackup arg = {0};
    |
    |     v = qmp_input_get_visitor(qiv);
    |+    visit_start_struct(v, NULL, NULL, 0, &err);
    |+    if (err) {
    |+        goto out;
    |+    }
    |     visit_type_BlockdevBackup_members(v, &arg, &err);
    |+    visit_end_struct(v, err ? NULL : &err);
    |     if (err) {
    |         goto out;
    |     }
    |@@ -527,7 +715,9 @@ out:
    |     qmp_input_visitor_cleanup(qiv);
    |     qdv = qapi_dealloc_visitor_new();
    |     v = qapi_dealloc_get_visitor(qdv);
    |+    visit_start_struct(v, NULL, NULL, 0, NULL);
    |     visit_type_BlockdevBackup_members(v, &arg, NULL);
    |+    visit_end_struct(v, NULL);
    |     qapi_dealloc_visitor_cleanup(qdv);
    | }
    
    The use of 'err ? NULL : &err' is temporary; a later patch will
    clean that up when it splits visit_end_struct().
    
    Prior to this patch, the fact that there was no final
    visit_end_struct() meant that even though we are using a strict
    input visit, the marshalling code was not detecting excess input
    at the top level (only in nested levels).  Fortunately, we have
    code in monitor.c:qmp_check_client_args() that also checks for
    no excess arguments at the top level.  But as the generated code
    is more compact than the manual check, a later patch will clean
    up monitor.c to drop the redundancy added here.
    
    Signed-off-by: default avatarEric Blake <eblake@redhat.com>
    Message-Id: <1461879932-9020-9-git-send-email-eblake@redhat.com>
    Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
Loading