Revision 4af9193a

b/monitor.c
4151 4151
}
4152 4152

  
4153 4153
/*
4154
 * Argument validation rules:
4155
 *
4156
 * 1. The argument must exist in cmd_args qdict
4157
 * 2. The argument type must be the expected one
4158
 *
4159
 * Special case: If the argument doesn't exist in cmd_args and
4160
 *               the QMP_ACCEPT_UNKNOWNS flag is set, then the
4161
 *               checking is skipped for it.
4162
 */
4163
static int check_client_args_type(const QDict *client_args,
4164
                                  const QDict *cmd_args, int flags)
4165
{
4166
    const QDictEntry *ent;
4167

  
4168
    for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){
4169
        QObject *obj;
4170
        QString *arg_type;
4171
        const QObject *client_arg = qdict_entry_value(ent);
4172
        const char *client_arg_name = qdict_entry_key(ent);
4173

  
4174
        obj = qdict_get(cmd_args, client_arg_name);
4175
        if (!obj) {
4176
            if (flags & QMP_ACCEPT_UNKNOWNS) {
4177
                /* handler accepts unknowns */
4178
                continue;
4179
            }
4180
            /* client arg doesn't exist */
4181
            qerror_report(QERR_INVALID_PARAMETER, client_arg_name);
4182
            return -1;
4183
        }
4184

  
4185
        arg_type = qobject_to_qstring(obj);
4186
        assert(arg_type != NULL);
4187

  
4188
        /* check if argument's type is correct */
4189
        switch (qstring_get_str(arg_type)[0]) {
4190
        case 'F':
4191
        case 'B':
4192
        case 's':
4193
            if (qobject_type(client_arg) != QTYPE_QSTRING) {
4194
                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
4195
                              "string");
4196
                return -1;
4197
            }
4198
        break;
4199
        case 'i':
4200
        case 'l':
4201
        case 'M':
4202
            if (qobject_type(client_arg) != QTYPE_QINT) {
4203
                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
4204
                              "int");
4205
                return -1; 
4206
            }
4207
            break;
4208
        case 'f':
4209
        case 'T':
4210
            if (qobject_type(client_arg) != QTYPE_QINT &&
4211
                qobject_type(client_arg) != QTYPE_QFLOAT) {
4212
                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
4213
                              "number");
4214
               return -1; 
4215
            }
4216
            break;
4217
        case 'b':
4218
        case '-':
4219
            if (qobject_type(client_arg) != QTYPE_QBOOL) {
4220
                qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name,
4221
                              "bool");
4222
               return -1; 
4223
            }
4224
            break;
4225
        case 'O':
4226
            assert(flags & QMP_ACCEPT_UNKNOWNS);
4227
            break;
4228
        case '/':
4229
        case '.':
4230
            /*
4231
             * These types are not supported by QMP and thus are not
4232
             * handled here. Fall through.
4233
             */
4234
        default:
4235
            abort();
4236
        }
4237
    }
4238

  
4239
    return 0;
4240
}
4241

  
4242
/*
4154 4243
 * - Check if the client has passed all mandatory args
4155 4244
 * - Set special flags for argument validation
4156 4245
 */
......
4227 4316
 * Client argument checking rules:
4228 4317
 *
4229 4318
 * 1. Client must provide all mandatory arguments
4319
 * 2. Each argument provided by the client must be expected
4320
 * 3. Each argument provided by the client must have the type expected
4321
 *    by the command
4230 4322
 */
4231 4323
static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args)
4232 4324
{
......
4241 4333
        goto out;
4242 4334
    }
4243 4335

  
4244
    /* TODO: Check client args type */
4336
    err = check_client_args_type(client_args, cmd_args, flags);
4245 4337

  
4246 4338
out:
4247 4339
    QDECREF(cmd_args);

Also available in: Unified diff