#include "asn_internal.h" #include "constraints.h" int asn_generic_no_constraint(asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { (void)type_descriptor; /* Unused argument */ (void)struct_ptr; /* Unused argument */ (void)cb; /* Unused argument */ (void)key; /* Unused argument */ /* Nothing to check */ return 0; } int asn_generic_unknown_constraint(asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, asn_app_constraint_failed_f *cb, void *key) { (void)type_descriptor; /* Unused argument */ (void)struct_ptr; /* Unused argument */ (void)cb; /* Unused argument */ (void)key; /* Unused argument */ /* Unknown how to check */ return 0; } struct errbufDesc { asn_TYPE_descriptor_t *failed_type; const void *failed_struct_ptr; char *errbuf; size_t errlen; }; static void _asn_i_ctfailcb(void *key, asn_TYPE_descriptor_t *td, const void *sptr, const char *fmt, ...) { struct errbufDesc *arg = key; va_list ap; ssize_t vlen; ssize_t maxlen; arg->failed_type = td; arg->failed_struct_ptr = sptr; maxlen = arg->errlen; if(maxlen <= 0) return; va_start(ap, fmt); vlen = vsnprintf(arg->errbuf, maxlen, fmt, ap); va_end(ap); if(vlen >= maxlen) { arg->errbuf[maxlen-1] = '\0'; /* Ensuring libc correctness */ arg->errlen = maxlen - 1; /* Not counting termination */ return; } else if(vlen >= 0) { arg->errbuf[vlen] = '\0'; /* Ensuring libc correctness */ arg->errlen = vlen; /* Not counting termination */ } else { /* * The libc on this system is broken. */ vlen = sizeof("") - 1; maxlen--; arg->errlen = vlen < maxlen ? vlen : maxlen; memcpy(arg->errbuf, "", arg->errlen); arg->errbuf[arg->errlen] = 0; } return; } int asn_check_constraints(asn_TYPE_descriptor_t *type_descriptor, const void *struct_ptr, char *errbuf, size_t *errlen) { struct errbufDesc arg; int ret; arg.failed_type = 0; arg.failed_struct_ptr = 0; arg.errbuf = errbuf; arg.errlen = errlen ? *errlen : 0; ret = type_descriptor->check_constraints(type_descriptor, struct_ptr, _asn_i_ctfailcb, &arg); if(ret == -1 && errlen) *errlen = arg.errlen; return ret; }