Exemple #1
0
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;
}