SilcStringprepStatus silc_stringprep(const unsigned char *bin, SilcUInt32 bin_len, SilcStringEncoding bin_encoding, const char *profile_name, SilcStringprepFlags flags, unsigned char **out, SilcUInt32 *out_len, SilcStringEncoding out_encoding) { Stringprep_profile_flags f = 0; const Stringprep_profile *profile; unsigned char *utf8s; SilcUInt32 utf8s_len; int ret; SILC_LOG_DEBUG(("Preparing string")); if (!bin || !bin_len || !profile_name) return SILC_STRINGPREP_ERR; /* Convert string to UTF-8 */ utf8s_len = silc_utf8_encoded_len(bin, bin_len, bin_encoding); if (!utf8s_len) return SILC_STRINGPREP_ERR_ENCODING; utf8s = silc_calloc(utf8s_len + 1, sizeof(*utf8s)); if (!utf8s) return SILC_STRINGPREP_ERR_OUT_OF_MEMORY; silc_utf8_encode(bin, bin_len, bin_encoding, utf8s, utf8s_len); /* Check profile. */ if (!strcmp(profile_name, SILC_IDENTIFIER_PREP)) profile = stringprep_silc_identifier_prep; else if (!strcmp(profile_name, SILC_IDENTIFIER_CH_PREP)) profile = stringprep_silc_identifier_ch_prep; else if (!strcmp(profile_name, SILC_IDENTIFIERC_PREP)) profile = stringprep_silc_identifierc_prep; else if (!strcmp(profile_name, SILC_CASEFOLD_PREP)) profile = stringprep_silc_casefold_prep; else return SILC_STRINGPREP_ERR_UNSUP_PROFILE; /* Translate flags */ if (!(flags & SILC_STRINGPREP_ALLOW_UNASSIGNED)) f |= STRINGPREP_NO_UNASSIGNED; /* Prepare */ ret = stringprep((char *)utf8s, utf8s_len, f, profile); SILC_LOG_DEBUG(("stringprep() return %d", ret)); /* Since the stringprep() doesn't allocate returned buffer, and stringprep_profile() doesn't do it correctly, we can't know how much space we must have for the conversion. Allocate more if it fails, and try again. */ if (ret == STRINGPREP_TOO_SMALL_BUFFER) { utf8s = silc_realloc(utf8s, sizeof(*utf8s) * ((utf8s_len * 2) + 1)); if (!utf8s) return SILC_STRINGPREP_ERR_OUT_OF_MEMORY; memset(utf8s + utf8s_len + 1, 0, utf8s_len); ret = stringprep((char *)utf8s, utf8s_len * 2, f, profile); SILC_LOG_DEBUG(("stringprep() return %d", ret)); } switch (ret) { case STRINGPREP_OK: ret = SILC_STRINGPREP_OK; break; case STRINGPREP_CONTAINS_UNASSIGNED: ret = SILC_STRINGPREP_ERR_UNASSIGNED; break; case STRINGPREP_CONTAINS_PROHIBITED: ret = SILC_STRINGPREP_ERR_PROHIBITED; break; case STRINGPREP_BIDI_BOTH_L_AND_RAL: ret = SILC_STRINGPREP_ERR_BIDI_RAL_WITH_L; break; case STRINGPREP_BIDI_LEADTRAIL_NOT_RAL: ret = SILC_STRINGPREP_ERR_BIDI_RAL; break; case STRINGPREP_BIDI_CONTAINS_PROHIBITED: ret = SILC_STRINGPREP_ERR_BIDI_PROHIBITED; break; case STRINGPREP_UNKNOWN_PROFILE: ret = SILC_STRINGPREP_ERR_UNSUP_PROFILE; break; case STRINGPREP_MALLOC_ERROR: ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY; break; default: ret = SILC_STRINGPREP_ERR; break; } /* Convert to desired output character encoding */ if (ret == SILC_STRINGPREP_OK) { if (out && out_len) { if (out_encoding != SILC_STRING_UTF8) { *out_len = silc_utf8_decoded_len(utf8s, strlen(utf8s), out_encoding); if (*out_len) { *out = silc_calloc(*out_len + 1, sizeof(**out)); if (*out) { silc_utf8_decode(utf8s, strlen(utf8s), out_encoding, *out, *out_len); } else { ret = SILC_STRINGPREP_ERR_OUT_OF_MEMORY; } } else { ret = SILC_STRINGPREP_ERR_ENCODING; } } else { *out_len = strlen(utf8s); *out = silc_memdup(utf8s, *out_len); } } } silc_free(utf8s); return (SilcStringprepStatus)ret; }
int main(int argc, char **argv) { SilcBool success = FALSE; unsigned char *s1, *s2, *s3, *s4; unsigned char t[16]; char h[32 + 1], str[40]; int l, opt, i; SilcUInt32 len; while ((opt = getopt(argc, argv, "hVd:")) != EOF) { switch(opt) { case 'h': printf("usage: test_silcstrutil\n"); exit(0); break; case 'V': printf("Secure Internet Live Conferencing\n"); exit(0); break; case 'd': silc_log_debug(TRUE); silc_log_debug_hexdump(TRUE); silc_log_quick(TRUE); if (optarg) silc_log_set_debug_string(optarg); else silc_log_set_debug_string("*strutil*,*errno*"); break; default: exit(1); break; } } /* Failure tests */ utf8failc(1); utf8failc(2); utf8failc(3); utf8failc(4); utf8failc(5); utf8failc(6); utf8failc(7); utf8failc(8); utf8failc(9); utf8failc(10); utf8failc(11); utf8failc(12); utf8failc(13); utf8failc(14); utf8failc(15); utf8failc(16); utf8failc(17); utf8failc(18); utf8failc(19); utf8failc(20); utf8failc(21); utf8failc(22); utf8failc(23); utf8failc(24); utf8failc(25); utf8failc(26); utf8failc(27); utf8failc(28); utf8failc(29); utf8failc(30); /* LDAP DN simple test */ s1 = "#&?*Pekka, \\Riikonen, <*****@*****.**>\xc4\x8d\\ "; SILC_LOG_DEBUG(("s1 = %s", s1)); /* To LDAP DN */ l = silc_utf8_decoded_len(s1, strlen(s1), SILC_STRING_LDAP_DN); if (!l) goto err; s3 = silc_calloc(l + 1, sizeof(*s3)); silc_utf8_decode(s1, strlen(s1), SILC_STRING_LDAP_DN, s3, l); SILC_LOG_DEBUG(("ldapdn = %s", s3)); /* To UTF-8 */ l = silc_utf8_encoded_len(s3, strlen(s3), SILC_STRING_LDAP_DN); if (!l) goto err; s4 = silc_calloc(l + 1, sizeof(*s4)); silc_utf8_encode(s3, strlen(s3), SILC_STRING_LDAP_DN, s4, l); SILC_LOG_DEBUG(("utf8 = %s", s4)); if (memcmp(s4, s1, strlen(s4))) { SILC_LOG_DEBUG(("UTF-8 mismatch")); goto err; } silc_free(s3); silc_free(s4); /* UTF-8 strcasecmp test */ SILC_LOG_DEBUG(("silc_utf8_strcasecmp test")); s1 = "Päivää vuan Yrjö"; s2 = "PÄIVÄÄ VUAN YRJÖ"; l = silc_utf8_encoded_len(s1, strlen(s1), SILC_STRING_LOCALE); if (!l) goto err; s3 = silc_calloc(l + 1, sizeof(*s3)); silc_utf8_encode(s1, strlen(s1), SILC_STRING_LOCALE, s3, l); l = silc_utf8_encoded_len(s2, strlen(s2), SILC_STRING_LOCALE); if (!l) goto err; s4 = silc_calloc(l + 1, sizeof(*s4)); silc_utf8_encode(s2, strlen(s2), SILC_STRING_LOCALE, s4, l); SILC_LOG_DEBUG(("%s == %s", s3, s4)); if (!silc_utf8_strcasecmp(s3, s4)) { SILC_LOG_DEBUG(("mismatch")); goto err; } SILC_LOG_DEBUG(("match")); silc_free(s3); silc_free(s4); /* Regex test */ SILC_LOG_DEBUG(("Simple regex test")); s1 = "foo,bar,silc,com"; SILC_LOG_DEBUG(("Find 'silc' from %s", s1)); if (!silc_string_match(s1, "silc")) goto err; SILC_LOG_DEBUG(("Regex match")); SILC_LOG_DEBUG(("Find 'foobar' from %s", s1)); if (silc_string_match(s1, "foobar")) goto err; SILC_LOG_DEBUG(("Regex not found (Ok)")); /* HEX to data, data to HEX tests */ for (i = 0; i < sizeof(t); i++) t[i] = i; silc_data2hex(t, sizeof(t), h, sizeof(h)); silc_hex2data(h, t, sizeof(t), &len); silc_snprintf(h, sizeof(h), "010203ffabdef9ab"); silc_hex2data(h, t, sizeof(t), &len); silc_data2hex(t, sizeof(t), h, sizeof(h)); /* snprintf test */ silc_snprintf(str, sizeof(str), "This is %@ rendered\n", render, "automatically"); SILC_LOG_DEBUG((str)); SILC_LOG_DEBUG(("This too %@ rendered", render, "is automatically")); success = TRUE; err: SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE")); fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE"); return !success; }