Exemplo n.º 1
0
int
sexp_iterator_check_type(struct sexp_iterator *iterator,
			 const uint8_t *type)
{
  return (sexp_iterator_enter_list(iterator)
	  && iterator->type == SEXP_ATOM
	  && !iterator->display
	  && strlen(type) == iterator->atom_length
	  && !memcmp(type, iterator->atom, iterator->atom_length)
	  && sexp_iterator_next(iterator));
}
Exemplo n.º 2
0
const uint8_t *
sexp_iterator_subexpr(struct sexp_iterator *iterator,
		      unsigned *length)
{
  unsigned start = iterator->start;
  if (!sexp_iterator_next(iterator))
    return 0;

  *length = iterator->start - start;
  return iterator->buffer + start;
}
Exemplo n.º 3
0
/* Skips the rest of the current list */
int
sexp_iterator_exit_list(struct sexp_iterator *iterator)
{
  if (!iterator->level)
    return 0;

  while(iterator->type != SEXP_END)
    if (!sexp_iterator_next(iterator))
      return 0;
      
  iterator->level--;

  return sexp_iterator_parse(iterator);
}
Exemplo n.º 4
0
const uint8_t *
sexp_iterator_check_types(struct sexp_iterator *iterator,
			  unsigned ntypes,
			  const uint8_t * const *types)
{
  if (sexp_iterator_enter_list(iterator)
      && iterator->type == SEXP_ATOM
      && !iterator->display)
    {
      unsigned i;
      for (i = 0; i<ntypes; i++)
	if (strlen(types[i]) == iterator->atom_length
	    && !memcmp(types[i], iterator->atom,
		       iterator->atom_length))
	  return sexp_iterator_next(iterator) ? types[i] : NULL;
    }
  return NULL;
}
Exemplo n.º 5
0
int
sexp_iterator_get_uint32(struct sexp_iterator *iterator,
                         uint32_t *x)
{
    if (iterator->type == SEXP_ATOM
            && !iterator->display
            && iterator->atom_length
            && iterator->atom[0] < 0x80)
    {
        size_t length = iterator->atom_length;
        const uint8_t *p = iterator->atom;

        /* Skip leading zeros. */
        while(length && !*p)
        {
            length--;
            p++;
        }

        switch(length)
        {
        case 0:
            *x = 0;
            break;
        case 1:
            *x = p[0];
            break;
        case 2:
            *x = READ_UINT16(p);
            break;
        case 3:
            *x = READ_UINT24(p);
            break;
        case 4:
            *x = READ_UINT32(p);
            break;
        default:
            return 0;
        }
        return sexp_iterator_next(iterator);
    }
    return 0;
}
Exemplo n.º 6
0
int
nettle_mpz_set_sexp(mpz_t x, unsigned limit, struct sexp_iterator *i)
{
  if (i->type == SEXP_ATOM
      && i->atom_length
      && !i->display)
    {
      /* Allow some extra here, for leading sign octets. */
      if (limit && (8 * i->atom_length > (16 + limit)))
	return 0;
      
      nettle_mpz_set_str_256_s(x, i->atom_length, i->atom);

      /* FIXME: How to interpret a limit for negative numbers? */
      if (limit && mpz_sizeinbase(x, 2) > limit)
	return 0;
      
      return sexp_iterator_next(i);
    }
  else
    return 0;
}
Exemplo n.º 7
0
int
sexp_iterator_assoc(struct sexp_iterator *iterator,
		    unsigned nkeys,
		    const uint8_t * const *keys,
		    struct sexp_iterator *values)
{
  TMP_DECL(found, int, NETTLE_MAX_SEXP_ASSOC);
  unsigned nfound;
  unsigned i;

  TMP_ALLOC(found, nkeys);
  for (i = 0; i<nkeys; i++)
    found[i] = 0;

  nfound = 0;
  
  for (;;)
    {
      switch (iterator->type)
	{
	case SEXP_LIST:

	  /* FIXME: Use sexp_iterator_check_type? Problem is to
	   * distinguish syntax errors from unkown keys (which we want
	   * to just ignore). */
	  if (!sexp_iterator_enter_list(iterator))
	    return 0;
	  
	  if (iterator->type == SEXP_ATOM
	      && !iterator->display)
	    {
	      /* Compare to the given keys */
	      for (i = 0; i<nkeys; i++)
		{
		  /* NOTE: The strlen could be put outside of the
		   * loop */
		  if (strlen(keys[i]) == iterator->atom_length
		      && !memcmp(keys[i], iterator->atom,
				 iterator->atom_length))
		    {
		      if (found[i])
			/* We don't allow duplicates */
			return 0;

		      /* Advance to point to value */
		      if (!sexp_iterator_next(iterator))
			return 0;

		      found[i] = 1;
		      nfound++;
		      
		      /* Record this position. */
		      values[i] = *iterator;
		      
		      break;
		    }
		}
	    }
	  if (!sexp_iterator_exit_list(iterator))
	    return 0;
	  break;
	case SEXP_ATOM:
	  /* Just ignore */
	  if (!sexp_iterator_next(iterator))
	    return 0;
	  break;
	  
	case SEXP_END:
	  return sexp_iterator_exit_list(iterator)
	    && (nfound == nkeys);

	default:
	  abort();
	}
    }
}
Exemplo n.º 8
0
void
test_main(void)
{
    struct sexp_iterator i;
    uint32_t x;

    ASSERT(sexp_iterator_first(&i, LDATA("")));
    ASSERT(i.type == SEXP_END);

    ASSERT(sexp_iterator_first(&i, LDATA("()")));
    ASSERT(i.type == SEXP_LIST
           && sexp_iterator_enter_list(&i)
           && i.type == SEXP_END
           && sexp_iterator_exit_list(&i)
           && i.type == SEXP_END);

    ASSERT(sexp_iterator_first(&i, LDATA("(")));
    ASSERT(i.type == SEXP_LIST
           && !sexp_iterator_enter_list(&i));

    /* Check integers. */
    ASSERT(sexp_iterator_first(&i, LDATA("1:\0"
                                         "1:\x11"
                                         "2:\x00\x11"
                                         "2:\x00\x80"
                                         "5:\x00\xaa\xbb\xcc\xdd")));
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x11);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0x80);
    ASSERT(sexp_iterator_get_uint32(&i, &x) && x == 0xaabbccdd);

    ASSERT(sexp_iterator_first(&i, LDATA("3:foo0:[3:bar]12:xxxxxxxxxxxx")));
    ASSERT(i.type == SEXP_ATOM
           && !i.display_length && !i.display
           && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)

           && sexp_iterator_next(&i) && i.type == SEXP_ATOM
           && !i.display_length && !i.display
           && !i.atom_length && i.atom

           && sexp_iterator_next(&i) && i.type == SEXP_ATOM
           && i.display_length == 3 && MEMEQ(3, "bar", i.display)
           && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)

           && sexp_iterator_next(&i) && i.type == SEXP_END);

    /* Same data, transport encoded. */

    {
        struct tstring *s
            = tstring_data(LDATA("{Mzpmb28=} {MDo=} {WzM6YmFyXTEyOnh4eHh4eHh4eHh4eA==}"));
        ASSERT(sexp_transport_iterator_first (&i, s->length, s->data));
        ASSERT(i.type == SEXP_ATOM
               && !i.display_length && !i.display
               && i.atom_length == 3 && MEMEQ(3, "foo", i.atom)

               && sexp_iterator_next(&i) && i.type == SEXP_ATOM
               && !i.display_length && !i.display
               && !i.atom_length && i.atom

               && sexp_iterator_next(&i) && i.type == SEXP_ATOM
               && i.display_length == 3 && MEMEQ(3, "bar", i.display)
               && i.atom_length == 12 && MEMEQ(12, "xxxxxxxxxxxx", i.atom)

               && sexp_iterator_next(&i) && i.type == SEXP_END);

    }
    {
        static const uint8_t *keys[2] = { "n", "e" };
        struct sexp_iterator v[2];

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n2:xx3:foo)0:(1:y)(1:e))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && sexp_iterator_assoc(&i, 2, keys, v));

        ASSERT(v[0].type == SEXP_ATOM
               && !v[0].display_length && !v[0].display
               && v[0].atom_length == 2 && MEMEQ(2, "xx", v[0].atom)

               && sexp_iterator_next(&v[0]) && v[0].type == SEXP_ATOM
               && !v[0].display_length && !v[0].display
               && v[0].atom_length == 3 && MEMEQ(3, "foo", v[0].atom)

               && sexp_iterator_next(&v[0]) && v[0].type == SEXP_END);

        ASSERT(v[1].type == SEXP_END);

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && !sexp_iterator_assoc(&i, 2, keys, v));

        ASSERT(sexp_iterator_first(&i, LDATA("((1:n)(1:n3:foo))")));
        ASSERT(sexp_iterator_enter_list(&i)
               && !sexp_iterator_assoc(&i, 2, keys, v));
    }
}