Harald Welte | d523a69 | 2015-08-30 23:11:19 +0200 | [diff] [blame^] | 1 | #include "asn_internal.h" |
| 2 | #include "constraints.h" |
| 3 | |
| 4 | int |
| 5 | asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor, |
| 6 | const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { |
| 7 | |
| 8 | (void)type_descriptor; /* Unused argument */ |
| 9 | (void)struct_ptr; /* Unused argument */ |
| 10 | (void)cb; /* Unused argument */ |
| 11 | (void)key; /* Unused argument */ |
| 12 | |
| 13 | /* Nothing to check */ |
| 14 | return 0; |
| 15 | } |
| 16 | |
| 17 | int |
| 18 | asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor, |
| 19 | const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { |
| 20 | |
| 21 | (void)type_descriptor; /* Unused argument */ |
| 22 | (void)struct_ptr; /* Unused argument */ |
| 23 | (void)cb; /* Unused argument */ |
| 24 | (void)key; /* Unused argument */ |
| 25 | |
| 26 | /* Unknown how to check */ |
| 27 | return 0; |
| 28 | } |
| 29 | |
| 30 | struct errbufDesc { |
| 31 | asn_TYPE_descriptor_t *failed_type; |
| 32 | const void *failed_struct_ptr; |
| 33 | char *errbuf; |
| 34 | size_t errlen; |
| 35 | }; |
| 36 | |
| 37 | static void |
| 38 | _asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) { |
| 39 | struct errbufDesc *arg = key; |
| 40 | va_list ap; |
| 41 | ssize_t vlen; |
| 42 | ssize_t maxlen; |
| 43 | |
| 44 | arg->failed_type = td; |
| 45 | arg->failed_struct_ptr = sptr; |
| 46 | |
| 47 | maxlen = arg->errlen; |
| 48 | if(maxlen <= 0) |
| 49 | return; |
| 50 | |
| 51 | va_start(ap, fmt); |
| 52 | vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap); |
| 53 | va_end(ap); |
| 54 | if(vlen >= maxlen) { |
| 55 | arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */ |
| 56 | arg->errlen = maxlen - 1; /* Not counting termination */ |
| 57 | return; |
| 58 | } else if(vlen >= 0) { |
| 59 | arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */ |
| 60 | arg->errlen = vlen; /* Not counting termination */ |
| 61 | } else { |
| 62 | /* |
| 63 | * The libc on this system is broken. |
| 64 | */ |
| 65 | vlen = sizeof("<broken vsnprintf>") - 1; |
| 66 | maxlen--; |
| 67 | arg->errlen = vlen < maxlen ? vlen : maxlen; |
| 68 | memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen); |
| 69 | arg->errbuf[arg->errlen] = 0; |
| 70 | } |
| 71 | |
| 72 | return; |
| 73 | } |
| 74 | |
| 75 | int |
| 76 | asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor, |
| 77 | const void *struct_ptr, char *errbuf, size_t *errlen) { |
| 78 | struct errbufDesc arg; |
| 79 | int ret; |
| 80 | |
| 81 | arg.failed_type = 0; |
| 82 | arg.failed_struct_ptr = 0; |
| 83 | arg.errbuf = errbuf; |
| 84 | arg.errlen = errlen ? *errlen : 0; |
| 85 | |
| 86 | ret = type_descriptor->check_constraints(type_descriptor, |
| 87 | struct_ptr, _asn_i_ctfailcb, &arg); |
| 88 | if(ret == -1 && errlen) |
| 89 | *errlen = arg.errlen; |
| 90 | |
| 91 | return ret; |
| 92 | } |
| 93 | |