| 6020 | } |
| 6021 | |
| 6022 | static int getarg(const char **s_, struct sqlclntstate *clnt, sparg_t *arg) |
| 6023 | { |
| 6024 | arg->mbuf = NULL; |
| 6025 | uint8_t quoted = 0; |
| 6026 | char *endptr; |
| 6027 | char *a, *b; |
| 6028 | const char *s = *s_; |
| 6029 | while (isspace(*s)) |
| 6030 | ++s; |
| 6031 | if (*s == ')' || *s == '\0') return arg_end; |
| 6032 | if ((s = getnext(s, &a, &b, arg->buf, sizeof(arg->buf))) == NULL) { |
| 6033 | goto err; |
| 6034 | } |
| 6035 | |
| 6036 | arg->type = arg_err; |
| 6037 | if (a != arg->buf) arg->mbuf = a; |
| 6038 | switch (*a) { |
| 6039 | case '"': |
| 6040 | case '\'': |
| 6041 | quoted = 1; |
| 6042 | if (a[1] != '@') { |
| 6043 | arg->type = arg_str; |
| 6044 | // lose the quotes |
| 6045 | arg->u.c = ++a; |
| 6046 | --b; |
| 6047 | b[0] = '\0'; |
| 6048 | break; |
| 6049 | } else { |
| 6050 | // lose the quotes |
| 6051 | ++a; |
| 6052 | --b; |
| 6053 | b[0] = '\0'; |
| 6054 | // fall through |
| 6055 | } |
| 6056 | case '@': |
| 6057 | arg->type = arg_param; |
| 6058 | ++a; // lose '@' |
| 6059 | if (param_count(clnt) == 0) { |
| 6060 | if (quoted) { |
| 6061 | arg->type = arg_str; |
| 6062 | arg->u.c = --a; |
| 6063 | } else { |
| 6064 | goto err; |
| 6065 | } |
| 6066 | } |
| 6067 | if (param_index(clnt, a, &arg->u.i) != 0) { |
| 6068 | goto err; |
| 6069 | } |
| 6070 | break; |
| 6071 | case 'x': |
| 6072 | arg->type = arg_blob; |
| 6073 | ++a; |
| 6074 | --b; |
| 6075 | if (*a != '\'' && *b != '\'') goto err; |
| 6076 | ++a; |
| 6077 | --b; // lose the quotes |
| 6078 | arg->u.b.length = b - a + 1; |
| 6079 | if (arg->u.b.length % 2 != 0) goto err; |
no test coverage detected