Peter Szilagyi | fbc56f9 | 2019-07-23 19:29:46 +0000 | [diff] [blame] | 1 | #include <asn_internal.h> |
| 2 | #include <constraints.h> |
| 3 | |
| 4 | int |
| 5 | asn_generic_no_constraint(const asn_TYPE_descriptor_t *type_descriptor, |
| 6 | const void *struct_ptr, |
| 7 | asn_app_constraint_failed_f *cb, void *key) { |
| 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(const asn_TYPE_descriptor_t *type_descriptor, |
| 19 | const void *struct_ptr, |
| 20 | asn_app_constraint_failed_f *cb, void *key) { |
| 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 | const 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, const asn_TYPE_descriptor_t *td, const void *sptr, |
| 39 | const char *fmt, ...) { |
| 40 | struct errbufDesc *arg = key; |
| 41 | va_list ap; |
| 42 | ssize_t vlen; |
| 43 | ssize_t maxlen; |
| 44 | |
| 45 | arg->failed_type = td; |
| 46 | arg->failed_struct_ptr = sptr; |
| 47 | |
| 48 | maxlen = arg->errlen; |
| 49 | if(maxlen <= 0) |
| 50 | return; |
| 51 | |
| 52 | va_start(ap, fmt); |
| 53 | vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap); |
| 54 | va_end(ap); |
| 55 | if(vlen >= maxlen) { |
| 56 | arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */ |
| 57 | arg->errlen = maxlen - 1; /* Not counting termination */ |
| 58 | return; |
| 59 | } else if(vlen >= 0) { |
| 60 | arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */ |
| 61 | arg->errlen = vlen; /* Not counting termination */ |
| 62 | } else { |
| 63 | /* |
| 64 | * The libc on this system is broken. |
| 65 | */ |
| 66 | vlen = sizeof("<broken vsnprintf>") - 1; |
| 67 | maxlen--; |
| 68 | arg->errlen = vlen < maxlen ? vlen : maxlen; |
| 69 | memcpy(arg->errbuf, "<broken vsnprintf>", arg->errlen); |
| 70 | arg->errbuf[arg->errlen] = 0; |
| 71 | } |
| 72 | |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | int |
| 77 | asn_check_constraints(const asn_TYPE_descriptor_t *type_descriptor, |
| 78 | const void *struct_ptr, char *errbuf, size_t *errlen) { |
| 79 | struct errbufDesc arg; |
| 80 | int ret; |
| 81 | |
| 82 | arg.failed_type = 0; |
| 83 | arg.failed_struct_ptr = 0; |
| 84 | arg.errbuf = errbuf; |
| 85 | arg.errlen = errlen ? *errlen : 0; |
| 86 | |
| 87 | ret = type_descriptor->encoding_constraints.general_constraints( |
| 88 | type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg); |
| 89 | if(ret == -1 && errlen) *errlen = arg.errlen; |
| 90 | |
| 91 | return ret; |
| 92 | } |
| 93 | |