| 10949 | } |
| 10950 | |
| 10951 | static int |
| 10952 | parse_hex(struct context *ctx, const struct token *token, |
| 10953 | const char *str, unsigned int len, |
| 10954 | void *buf, unsigned int size) |
| 10955 | { |
| 10956 | const struct arg *arg_data = pop_args(ctx); |
| 10957 | const struct arg *arg_len = pop_args(ctx); |
| 10958 | const struct arg *arg_addr = pop_args(ctx); |
| 10959 | char tmp[16]; /* Ought to be enough. */ |
| 10960 | int ret; |
| 10961 | unsigned int hexlen = len; |
| 10962 | unsigned int length = 256; |
| 10963 | uint8_t hex_tmp[length]; |
| 10964 | |
| 10965 | /* Arguments are expected. */ |
| 10966 | if (!arg_data) |
| 10967 | return -1; |
| 10968 | if (!arg_len) { |
| 10969 | push_args(ctx, arg_data); |
| 10970 | return -1; |
| 10971 | } |
| 10972 | if (!arg_addr) { |
| 10973 | push_args(ctx, arg_len); |
| 10974 | push_args(ctx, arg_data); |
| 10975 | return -1; |
| 10976 | } |
| 10977 | size = arg_data->size; |
| 10978 | /* Bit-mask fill is not supported. */ |
| 10979 | if (arg_data->mask) |
| 10980 | goto error; |
| 10981 | if (!ctx->object) |
| 10982 | return len; |
| 10983 | |
| 10984 | /* translate bytes string to array. */ |
| 10985 | if (str[0] == '0' && ((str[1] == 'x') || |
| 10986 | (str[1] == 'X'))) { |
| 10987 | str += 2; |
| 10988 | hexlen -= 2; |
| 10989 | } |
| 10990 | if (hexlen > length) |
| 10991 | goto error; |
| 10992 | ret = parse_hex_string(str, hex_tmp, &hexlen); |
| 10993 | if (ret < 0) |
| 10994 | goto error; |
| 10995 | /* Check the converted binary fits into data buffer. */ |
| 10996 | if (hexlen > size) |
| 10997 | goto error; |
| 10998 | /* Let parse_int() fill length information first. */ |
| 10999 | ret = snprintf(tmp, sizeof(tmp), "%u", hexlen); |
| 11000 | if (ret < 0) |
| 11001 | goto error; |
| 11002 | /* Save length if requested. */ |
| 11003 | if (arg_len->size) { |
| 11004 | push_args(ctx, arg_len); |
| 11005 | ret = parse_int(ctx, token, tmp, ret, NULL, 0); |
| 11006 | if (ret < 0) { |
| 11007 | pop_args(ctx); |
| 11008 | goto error; |