1/* 2 * ICU glue 3 */ 4 5#include "windlocl.h" 6#include <unicode/usprep.h> 7 8int 9wind_stringprep(const uint32_t *in, size_t in_len, 10 uint32_t *out, size_t *out_len, 11 wind_profile_flags flags) 12{ 13 UErrorCode status = 0; 14 UStringPrepProfile *profile; 15 UStringPrepProfileType type; 16 UChar *uin, *dest; 17 int32_t len; 18 size_t n; 19 20 if (in_len > UINT_MAX / sizeof(in[0]) || (*out_len) > UINT_MAX / sizeof(out[0])) 21 return EINVAL; 22 23 if (flags & WIND_PROFILE_SASL) 24 type = USPREP_RFC4013_SASLPREP; 25 else 26 return EINVAL; 27 28 /* 29 * Should cache profile 30 */ 31 32 profile = usprep_openByType(type, &status); 33 if (profile == NULL) 34 return ENOENT; 35 36 uin = malloc(in_len * sizeof(uin[0])); 37 dest = malloc(*out_len * sizeof(dest[0])); 38 if (uin == NULL || dest == NULL) { 39 free(uin); 40 free(dest); 41 usprep_close(profile); 42 return ENOMEM; 43 } 44 45 /* ucs42ucs2 - don't care about surogates */ 46 for (n = 0; n < in_len; n++) 47 uin[n] = in[n]; 48 49 status = 0; 50 51 len = usprep_prepare(profile, uin, (int32_t)in_len, dest, (int32_t)*out_len, 52 USPREP_DEFAULT, NULL, &status); 53 54 if (len < 0 || status) { 55 free(dest); 56 free(uin); 57 return EINVAL; 58 } 59 60 for (n = 0; n < len; n++) 61 out[n] = dest[n]; 62 63 *out_len = len; 64 65 free(dest); 66 free(uin); 67 68 return 0; 69} 70