Ejemplo n.º 1
0
/**
 * idna_to_unicode_4z4z:
 * @input: zero-terminated Unicode string.
 * @output: pointer to newly allocated output Unicode string.
 * @flags: IDNA flags, e.g. IDNA_ALLOW_UNASSIGNED or IDNA_USE_STD3_ASCII_RULES.
 *
 * Convert possibly ACE encoded domain name in UCS-4 format into a
 * UCS-4 string.  The domain name may contain several labels,
 * separated by dots.  The output buffer must be deallocated by the
 * caller.
 *
 * Return value: Returns IDNA_SUCCESS on success, or error code.
 **/
int
idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags)
{
  const uint32_t *start = input;
  const uint32_t *end = input;
  uint32_t *buf;
  size_t buflen;
  uint32_t *out = NULL;
  size_t outlen = 0;

  *output = NULL;

  do
    {
      end = start;

      for (; *end && !DOTP (*end); end++)
	;

      buflen = end - start;
      buf = malloc (sizeof (buf[0]) * (buflen + 1));
      if (!buf)
	return IDNA_MALLOC_ERROR;

      idna_to_unicode_44i (start, end - start, buf, &buflen, flags);
      /* don't check return value as per specification! */

      if (out)
	{
	  uint32_t *newp = realloc (out,
				    sizeof (out[0])
				    * (outlen + 1 + buflen + 1));
	  if (!newp)
	    {
	      free (buf);
	      free (out);
	      return IDNA_MALLOC_ERROR;
	    }
	  out = newp;
	  out[outlen++] = 0x002E;	/* '.' (full stop) */
	  memcpy (out + outlen, buf, sizeof (buf[0]) * buflen);
	  outlen += buflen;
	  out[outlen] = 0x0;
	  free (buf);
	}
      else
	{
	  out = buf;
	  outlen = buflen;
	  out[outlen] = 0x0;
	}

      start = end + 1;
    }
  while (*end);

  *output = out;

  return IDNA_SUCCESS;
}
int dns_label_undo_idna(const char *encoded, size_t encoded_size, char *decoded, size_t decoded_max) {
#ifdef HAVE_LIBIDN
        size_t input_size, output_size;
        _cleanup_free_ uint32_t *input = NULL;
        _cleanup_free_ char *result = NULL;
        uint32_t *output = NULL;
        size_t w;

        /* To be invoked after unescaping */

        assert(encoded);
        assert(decoded);

        if (encoded_size < sizeof(IDNA_ACE_PREFIX)-1)
                return 0;

        if (memcmp(encoded, IDNA_ACE_PREFIX, sizeof(IDNA_ACE_PREFIX) -1) != 0)
                return 0;

        input = stringprep_utf8_to_ucs4(encoded, encoded_size, &input_size);
        if (!input)
                return -ENOMEM;

        output_size = input_size;
        output = newa(uint32_t, output_size);

        idna_to_unicode_44i(input, input_size, output, &output_size, 0);

        result = stringprep_ucs4_to_utf8(output, output_size, NULL, &w);
        if (!result)
                return -ENOMEM;
        if (w <= 0)
                return 0;
        if (w+1 > decoded_max)
                return -EINVAL;

        memcpy(decoded, result, w+1);
        return w;
#else
        return 0;
#endif
}
Ejemplo n.º 3
0
void
doit (void)
{
  char label[100];
  uint32_t *ucs4label = NULL;
  uint32_t tmp[100];
  size_t len, len2, i;
  int rc;

  for (i = 0; i < sizeof (idna) / sizeof (idna[0]); i++)
    {
      if (debug)
	printf ("IDNA entry %d: %s\n", i, idna[i].name);

      if (debug)
	{
	  printf ("in:\n");
	  ucs4print (idna[i].in, idna[i].inlen);
	}

      rc = idna_to_ascii_4i (idna[i].in, idna[i].inlen, label, idna[i].flags);
      if (rc != idna[i].toasciirc)
	{
	  fail ("IDNA entry %d failed: %d\n", i, rc);
	  if (debug)
	    printf ("FATAL\n");
	  continue;
	}

      if (debug && rc == IDNA_SUCCESS)
	{
	  printf ("computed out: %s\n", label);
	  printf ("expected out: %s\n", idna[i].out);
	}
      else if (debug)
	printf ("returned %d expected %d\n", rc, idna[i].toasciirc);

      if (rc == IDNA_SUCCESS)
	{
	  if (strlen (idna[i].out) != strlen (label) ||
	      strcasecmp (idna[i].out, label) != 0)
	    {
	      fail ("IDNA entry %d failed\n", i);
	      if (debug)
		printf ("ERROR\n");
	    }
	  else if (debug)
	    printf ("OK\n");
	}
      else if (debug)
	printf ("OK\n");

      if (ucs4label)
	free (ucs4label);

      ucs4label = stringprep_utf8_to_ucs4 (idna[i].out, -1, &len);

      if (debug)
	{
	  printf ("in: %s (%d==%d)\n", idna[i].out, strlen (idna[i].out),
		  len);
	  ucs4print (ucs4label, len);
	}

      len2 = sizeof (tmp) / sizeof (tmp[0]);
      rc = idna_to_unicode_44i (ucs4label, len, tmp, &len2, idna[i].flags);
      if (debug)
	{
	  printf ("expected out (%d):\n",
		  rc == IDNA_SUCCESS ? idna[i].inlen : len);
	  if (rc == IDNA_SUCCESS)
	    ucs4print (idna[i].in, idna[i].inlen);
	  else
	    ucs4print (ucs4label, len);

	  printf ("computed out (%d):\n", len2);
	  ucs4print (tmp, len2);
	}

      if (rc != idna[i].tounicoderc)
	{
	  fail ("IDNA entry %d failed: %d\n", i, rc);
	  if (debug)
	    printf ("FATAL\n");
	  continue;
	}

      if ((rc == IDNA_SUCCESS && (len2 != idna[i].inlen ||
				  memcmp (idna[i].in, tmp, len2) != 0)) ||
	  (rc != IDNA_SUCCESS && (len2 != len ||
				  memcmp (ucs4label, tmp, len) != 0)))
	{
	  if (debug)
	    {
	      if (rc == IDNA_SUCCESS)
		printf ("len=%d len2=%d\n", len2, idna[i].inlen);
	      else
		printf ("len=%d len2=%d\n", len, len2);
	    }
	  fail ("IDNA entry %d failed\n", i);
	  if (debug)
	    printf ("ERROR\n");
	}
      else if (debug)
	printf ("OK\n\n");
    }

  if (ucs4label)
    free (ucs4label);
}