int wind_utf8ucs4_copy(const char *in, uint32_t **out, size_t *out_len) { int ret; ret = wind_utf8ucs4_length(in, out_len); if (ret) return ret; if (*out_len > UINT_MAX / sizeof((*out)[0])) return ERANGE; if (*out_len == 0) return 0; *out = malloc(*out_len * sizeof((*out)[0])); if (*out == NULL) { *out_len = 0; return ENOMEM; } ret = wind_utf8ucs4(in, *out, out_len); if (ret) { free(*out); *out = NULL; *out_len = 0; } return ret; }
static int dsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen) { wind_profile_flags flags; size_t i, len; int ret; uint32_t *name; *rname = NULL; *rlen = 0; switch(ds->element) { case choice_DirectoryString_ia5String: flags = WIND_PROFILE_LDAP; COPYVOIDARRAY(ds, ia5String, len, name); break; case choice_DirectoryString_printableString: flags = WIND_PROFILE_LDAP; flags |= WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE; COPYVOIDARRAY(ds, printableString, len, name); break; case choice_DirectoryString_teletexString: flags = WIND_PROFILE_LDAP_CASE; COPYCHARARRAY(ds, teletexString, len, name); break; case choice_DirectoryString_bmpString: flags = WIND_PROFILE_LDAP; COPYVALARRAY(ds, bmpString, len, name); break; case choice_DirectoryString_universalString: flags = WIND_PROFILE_LDAP; COPYVALARRAY(ds, universalString, len, name); break; case choice_DirectoryString_utf8String: flags = WIND_PROFILE_LDAP; ret = wind_utf8ucs4_length(ds->u.utf8String, &len); if (ret) return ret; name = malloc(len * sizeof(name[0])); if (name == NULL) return ENOMEM; ret = wind_utf8ucs4(ds->u.utf8String, name, &len); if (ret) { free(name); return ret; } break; default: _hx509_abort("unknown directory type: %d", ds->element); } *rlen = len; /* try a couple of times to get the length right, XXX gross */ for (i = 0; i < 4; i++) { *rlen = *rlen * 2; *rname = malloc(*rlen * sizeof((*rname)[0])); ret = wind_stringprep(name, len, *rname, rlen, flags); if (ret == WIND_ERR_OVERRUN) { free(*rname); *rname = NULL; continue; } else break; } free(name); if (ret) { if (*rname) free(*rname); *rname = NULL; *rlen = 0; return ret; } return 0; }
int main(void) { unsigned failures = 0; unsigned i; const char **s; int ret; size_t len, len2; uint32_t u[MAX_LENGTH]; char str[MAX_LENGTH * 4]; for (s = failing_testcases; *s != NULL; ++s) { len = MAX_LENGTH; ret = wind_utf8ucs4(*s, u, &len); if (ret == 0) { printf("utf8 decode of \"%s\" should have failed\n", *s); ++failures; } } for (i = 0; i < sizeof(testcases)/sizeof(testcases[0]); ++i) { const struct testcase *t = &testcases[i]; ret = wind_utf8ucs4_length(t->utf8_str, &len); if (ret) { printf("utf8ucs4 length of \"%s\" should have succeeded\n", t->utf8_str); ++failures; continue; } if (len != t->len) { printf("utf8ucs4_length of \"%s\" has wrong length: " "expected: %u, actual: %u\n", t->utf8_str, (unsigned int)t->len, (unsigned int)len); ++failures; continue; } len = MAX_LENGTH; ret = wind_utf8ucs4(t->utf8_str, u, &len); if (ret) { printf("utf8 decode of \"%s\" should have succeeded\n", t->utf8_str); ++failures; continue; } if (len != t->len) { printf("utf8 decode of \"%s\" has wrong length: " "expected: %u, actual: %u\n", t->utf8_str, (unsigned int)t->len, (unsigned int)len); ++failures; continue; } if (memcmp(t->u, u, len * sizeof(uint32_t)) != 0) { printf("utf8 decode of \"%s\" has wrong data\n", t->utf8_str); ++failures; continue; } if (t->invalid_ucs2 == 0) { len2 = sizeof(str); ret = wind_ucs4utf8(u, len, str, &len2); if (ret) { printf("ucs4 decode of \"%s\" should have succeeded\n", t->utf8_str); ++failures; continue; } } } return failures != 0; }