/** Run unit tests for smartlist set manipulation functions. */
static void
test_container_smartlist_overlap(void *unused)
{
  smartlist_t *sl = smartlist_create();
  smartlist_t *ints = smartlist_create();
  smartlist_t *odds = smartlist_create();
  smartlist_t *evens = smartlist_create();
  smartlist_t *primes = smartlist_create();
  int i;
  for (i=1; i < 10; i += 2)
    smartlist_add(odds, (void*)(uintptr_t)i);
  for (i=0; i < 10; i += 2)
    smartlist_add(evens, (void*)(uintptr_t)i);

  /* add_all */
  smartlist_add_all(ints, odds);
  smartlist_add_all(ints, evens);
  tt_int_op(smartlist_len(ints), ==, 10);

  smartlist_add(primes, (void*)2);
  smartlist_add(primes, (void*)3);
  smartlist_add(primes, (void*)5);
  smartlist_add(primes, (void*)7);

  /* overlap */
  tt_assert(smartlist_overlap(ints, odds));
  tt_assert(smartlist_overlap(odds, primes));
  tt_assert(smartlist_overlap(evens, primes));
  tt_assert(!smartlist_overlap(odds, evens));

  /* intersect */
  smartlist_add_all(sl, odds);
  smartlist_intersect(sl, primes);
  tt_int_op(smartlist_len(sl), ==, 3);
  tt_assert(smartlist_isin(sl, (void*)3));
  tt_assert(smartlist_isin(sl, (void*)5));
  tt_assert(smartlist_isin(sl, (void*)7));

  /* subtract */
  smartlist_add_all(sl, primes);
  smartlist_subtract(sl, odds);
  tt_int_op(smartlist_len(sl), ==, 1);
  tt_assert(smartlist_isin(sl, (void*)2));

 end:
  smartlist_free(odds);
  smartlist_free(evens);
  smartlist_free(ints);
  smartlist_free(primes);
  smartlist_free(sl);
}
Example #2
0
/** Return true iff some element E of sl2 has smartlist_isin(sl1,E).
 */
int
smartlist_overlap(const smartlist_t *sl1, const smartlist_t *sl2)
{
  int i;
  for (i=0; i < sl2->num_used; i++)
    if (smartlist_isin(sl1, sl2->list[i]))
      return 1;
  return 0;
}
Example #3
0
/** Remove every element E of sl1 such that !smartlist_isin(sl2,E).
 * Does not preserve the order of sl1.
 */
void
smartlist_intersect(smartlist_t *sl1, const smartlist_t *sl2)
{
  int i;
  for (i=0; i < sl1->num_used; i++)
    if (!smartlist_isin(sl2, sl1->list[i])) {
      sl1->list[i] = sl1->list[--sl1->num_used]; /* swap with the end */
      i--; /* so we process the new i'th element */
    }
}
/** Run unit tests for basic dynamic-sized array functionality. */
static void
test_container_smartlist_basic(void *unused)
{
  smartlist_t *sl;

  /* XXXX test sort_digests, uniq_strings, uniq_digests */

  /* Test smartlist add, del_keeporder, insert, get. */
  sl = smartlist_create();
  smartlist_add(sl, (void*)1);
  smartlist_add(sl, (void*)2);
  smartlist_add(sl, (void*)3);
  smartlist_add(sl, (void*)4);
  smartlist_del_keeporder(sl, 1);
  smartlist_insert(sl, 1, (void*)22);
  smartlist_insert(sl, 0, (void*)0);
  smartlist_insert(sl, 5, (void*)555);
  tt_ptr_op(smartlist_get(sl,0), ==, (void*)0);
  tt_ptr_op(smartlist_get(sl,1), ==, (void*)1);
  tt_ptr_op(smartlist_get(sl,2), ==, (void*)22);
  tt_ptr_op(smartlist_get(sl,3), ==, (void*)3);
  tt_ptr_op(smartlist_get(sl,4), ==, (void*)4);
  tt_ptr_op(smartlist_get(sl,5), ==, (void*)555);
  /* Try deleting in the middle. */
  smartlist_del(sl, 1);
  tt_ptr_op(smartlist_get(sl, 1), ==, (void*)555);
  /* Try deleting at the end. */
  smartlist_del(sl, 4);
  tt_int_op(smartlist_len(sl), ==, 4);

  /* test isin. */
  tt_assert(smartlist_isin(sl, (void*)3));
  tt_assert(!smartlist_isin(sl, (void*)99));

 end:
  smartlist_free(sl);
}
/** Run unit tests for smartlist-of-strings functionality. */
static void
test_container_smartlist_strings(void *unused)
{
  smartlist_t *sl = smartlist_create();
  char *cp=NULL, *cp_alloc=NULL;
  size_t sz;

  /* Test split and join */
  tt_int_op(smartlist_len(sl), ==, 0);
  smartlist_split_string(sl, "abc", ":", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 1);
  tt_str_op(smartlist_get(sl, 0), ==, "abc");
  smartlist_split_string(sl, "a::bc::", "::", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 4);
  tt_str_op(smartlist_get(sl, 1), ==, "a");
  tt_str_op(smartlist_get(sl, 2), ==, "bc");
  tt_str_op(smartlist_get(sl, 3), ==, "");
  cp_alloc = smartlist_join_strings(sl, "", 0, NULL);
  tt_str_op(cp_alloc, ==, "abcabc");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "!", 0, NULL);
  tt_str_op(cp_alloc, ==, "abc!a!bc!");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  tt_str_op(cp_alloc, ==, "abcXYaXYbcXY");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  tt_str_op(cp_alloc, ==, "abcXYaXYbcXYXY");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "", 1, NULL);
  tt_str_op(cp_alloc, ==, "abcabc");
  free(cp_alloc);

  smartlist_split_string(sl, "/def/  /ghijk", "/", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 8);
  tt_str_op(smartlist_get(sl, 4), ==, "");
  tt_str_op(smartlist_get(sl, 5), ==, "def");
  tt_str_op(smartlist_get(sl, 6), ==, "  ");
  tt_str_op(smartlist_get(sl, 7), ==, "ghijk");
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "a,bbd,cdef", ",", SPLIT_SKIP_SPACE, 0);
  tt_int_op(smartlist_len(sl), ==, 3);
  tt_str_op(smartlist_get(sl,0), ==, "a");
  tt_str_op(smartlist_get(sl,1), ==, "bbd");
  tt_str_op(smartlist_get(sl,2), ==, "cdef");
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE, 0);
  tt_int_op(smartlist_len(sl), ==, 8);
  tt_str_op(smartlist_get(sl,3), ==, "z");
  tt_str_op(smartlist_get(sl,4), ==, "zhasd");
  tt_str_op(smartlist_get(sl,5), ==, "");
  tt_str_op(smartlist_get(sl,6), ==, "bnud");
  tt_str_op(smartlist_get(sl,7), ==, "");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, " ab\tc \td ef  ", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 4);
  tt_str_op(smartlist_get(sl,0), ==, "ab");
  tt_str_op(smartlist_get(sl,1), ==, "c");
  tt_str_op(smartlist_get(sl,2), ==, "d");
  tt_str_op(smartlist_get(sl,3), ==, "ef");
  smartlist_split_string(sl, "ghi\tj", NULL,
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 6);
  tt_str_op(smartlist_get(sl,4), ==, "ghi");
  tt_str_op(smartlist_get(sl,5), ==, "j");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  cp_alloc = smartlist_join_strings(sl, "XY", 0, NULL);
  tt_str_op(cp_alloc, ==, "");
  free(cp_alloc);
  cp_alloc = smartlist_join_strings(sl, "XY", 1, NULL);
  tt_str_op(cp_alloc, ==, "XY");
  free(cp_alloc);

  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 3);
  tt_str_op(smartlist_get(sl, 0), ==, "z");
  tt_str_op(smartlist_get(sl, 1), ==, "zhasd");
  tt_str_op(smartlist_get(sl, 2), ==, "bnud");
  smartlist_split_string(sl, " z <> zhasd <>  <> bnud<>   ", "<>",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
  tt_int_op(smartlist_len(sl), ==, 5);
  tt_str_op(smartlist_get(sl, 3), ==, "z");
  tt_str_op(smartlist_get(sl, 4), ==, "zhasd <>  <> bnud<>");
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  smartlist_split_string(sl, "abcd\n", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 1);
  tt_str_op(smartlist_get(sl, 0), ==, "abcd");
  smartlist_split_string(sl, "efgh", "\n",
                         SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  tt_int_op(smartlist_len(sl), ==, 2);
  tt_str_op(smartlist_get(sl, 1), ==, "efgh");

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  /* Test swapping, shuffling, and sorting. */
  smartlist_split_string(sl, "the,onion,router,by,arma,and,nickm", ",", 0, 0);
  tt_int_op(smartlist_len(sl), ==, 7);
  smartlist_sort(sl, _compare_strs);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "and,arma,by,nickm,onion,router,the");
  free(cp_alloc);
  smartlist_swap(sl, 1, 5);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "and,router,by,nickm,onion,arma,the");
  free(cp_alloc);
  smartlist_shuffle(sl);
  tt_int_op(smartlist_len(sl), ==, 7);
  tt_assert(smartlist_string_isin(sl, "and"));
  tt_assert(smartlist_string_isin(sl, "router"));
  tt_assert(smartlist_string_isin(sl, "by"));
  tt_assert(smartlist_string_isin(sl, "nickm"));
  tt_assert(smartlist_string_isin(sl, "onion"));
  tt_assert(smartlist_string_isin(sl, "arma"));
  tt_assert(smartlist_string_isin(sl, "the"));

  /* Test bsearch. */
  smartlist_sort(sl, _compare_strs);
  tt_str_op(smartlist_bsearch(sl, "zNicKM",
                              _compare_without_first_ch), ==, "nickm");
  tt_str_op(smartlist_bsearch(sl, " AND", _compare_without_first_ch), ==, "and");
  tt_ptr_op(smartlist_bsearch(sl, " ANz", _compare_without_first_ch), ==, NULL);

  /* Test bsearch_idx */
  {
    int f;
    tt_int_op(smartlist_bsearch_idx(sl," aaa",_compare_without_first_ch,&f),
              ==, 0);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," and",_compare_without_first_ch,&f),
              ==, 0);
    tt_int_op(f, ==, 1);
    tt_int_op(smartlist_bsearch_idx(sl," arm",_compare_without_first_ch,&f),
              ==, 1);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," arma",_compare_without_first_ch,&f),
              ==, 1);
    tt_int_op(f, ==, 1);
    tt_int_op(smartlist_bsearch_idx(sl," armb",_compare_without_first_ch,&f),
              ==, 2);
    tt_int_op(f, ==, 0);
    tt_int_op(smartlist_bsearch_idx(sl," zzzz",_compare_without_first_ch,&f),
              ==, 7);
    tt_int_op(f, ==, 0);
  }

  /* Test reverse() and pop_last() */
  smartlist_reverse(sl);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "the,router,onion,nickm,by,arma,and");
  free(cp_alloc);
  cp_alloc = smartlist_pop_last(sl);
  tt_str_op(cp_alloc, ==, "and");
  free(cp_alloc);
  tt_int_op(smartlist_len(sl), ==, 6);
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);
  cp_alloc = smartlist_pop_last(sl);
  tt_ptr_op(cp_alloc, ==, NULL);

  /* Test uniq() */
  smartlist_split_string(sl,
                     "50,noon,radar,a,man,a,plan,a,canal,panama,radar,noon,50",
                     ",", 0, 0);
  smartlist_sort(sl, _compare_strs);
  smartlist_uniq(sl, _compare_strs, free);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "50,a,canal,man,noon,panama,plan,radar");
  free(cp_alloc);

  /* Test string_isin and isin_case and num_isin */
  tt_assert(smartlist_string_isin(sl, "noon"));
  tt_assert(!smartlist_string_isin(sl, "noonoon"));
  tt_assert(smartlist_string_isin_case(sl, "nOOn"));
  tt_assert(!smartlist_string_isin_case(sl, "nooNooN"));
  tt_assert(smartlist_string_num_isin(sl, 50));
  tt_assert(!smartlist_string_num_isin(sl, 60));

  /* Test smartlist_choose */
  {
    int i;
    int allsame = 1;
    int allin = 1;
    void *first = smartlist_choose(sl);
    tt_assert(smartlist_isin(sl, first));
    for (i = 0; i < 100; ++i) {
      void *second = smartlist_choose(sl);
      if (second != first)
        allsame = 0;
      if (!smartlist_isin(sl, second))
        allin = 0;
    }
    tt_assert(!allsame);
    tt_assert(allin);
  }
  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_clear(sl);

  /* Test string_remove and remove and join_strings2 */
  smartlist_split_string(sl,
                    "Some say the Earth will end in ice and some in fire",
                    " ", 0, 0);
  cp = smartlist_get(sl, 4);
  tt_str_op(cp, ==, "will");
  smartlist_add(sl, cp);
  smartlist_remove(sl, cp);
  free(cp);
  cp_alloc = smartlist_join_strings(sl, ",", 0, NULL);
  tt_str_op(cp_alloc, ==, "Some,say,the,Earth,fire,end,in,ice,and,some,in");
  free(cp_alloc);
  smartlist_string_remove(sl, "in");
  cp_alloc = smartlist_join_strings2(sl, "+XX", 1, 0, &sz);
  tt_str_op(cp_alloc, ==, "Some+say+the+Earth+fire+end+some+ice+and");
  tt_int_op((int)sz, ==, 40);

 end:

  SMARTLIST_FOREACH(sl, char *, cp, free(cp));
  smartlist_free(sl);
  free(cp_alloc);
}
  /* non-unique, sorted. */
  smartlist_split_string(sl2,
                         "Ambush Anchorman Anchorman Anemias Anemias Bacon "
                         "Crossbowmen Inhumane Insurance Knish Know Manners "
                         "Manners Maraschinos Wombats Wombats Work",
                         " ", 0, 0);
  SMARTLIST_FOREACH_JOIN(sl, char *, cp1,
                         sl2, char *, cp2,
                         strcmp(cp1,cp2),
                         smartlist_add(sl3, cp2)) {
    tt_str_op(cp1, ==, cp2);
    smartlist_add(sl4, cp1);
  } SMARTLIST_FOREACH_JOIN_END(cp1, cp2);

  SMARTLIST_FOREACH(sl3, const char *, cp,
                    tt_assert(smartlist_isin(sl2, cp) &&
                                !smartlist_string_isin(sl, cp)));
  SMARTLIST_FOREACH(sl4, const char *, cp,
                    tt_assert(smartlist_isin(sl, cp) &&
                                smartlist_string_isin(sl2, cp)));
  joined = smartlist_join_strings(sl3, ",", 0, NULL);
  tt_str_op(joined, ==, "Anemias,Anemias,Crossbowmen,Work");
  free(joined);
  joined = smartlist_join_strings(sl4, ",", 0, NULL);
  tt_str_op(joined, ==,
            "Ambush,Anchorman,Anchorman,Bacon,Inhumane,Insurance,"
            "Knish,Know,Manners,Manners,Maraschinos,Wombats,Wombats");

 end:
  smartlist_free(sl4);
  smartlist_free(sl3);
Example #7
0
/** Verify that circuit <b>c</b> has all of its invariants
 * correct. Trigger an assert if anything is invalid.
 */
void
assert_circuit_ok(const circuit_t *c)
{
  edge_connection_t *conn;
  const or_circuit_t *or_circ = NULL;
  const origin_circuit_t *origin_circ = NULL;

  tor_assert(c);
  tor_assert(c->magic == ORIGIN_CIRCUIT_MAGIC || c->magic == OR_CIRCUIT_MAGIC);
  tor_assert(c->purpose >= _CIRCUIT_PURPOSE_MIN &&
             c->purpose <= _CIRCUIT_PURPOSE_MAX);

  {
    /* Having a separate variable for this pleases GCC 4.2 in ways I hope I
     * never understand. -NM. */
    circuit_t *nonconst_circ = (circuit_t*) c;
    if (CIRCUIT_IS_ORIGIN(c))
      origin_circ = TO_ORIGIN_CIRCUIT(nonconst_circ);
    else
      or_circ = TO_OR_CIRCUIT(nonconst_circ);
  }

  if (c->n_conn) {
    tor_assert(!c->n_hop);

    if (c->n_circ_id) {
      /* We use the _impl variant here to make sure we don't fail on marked
       * circuits, which would not be returned by the regular function. */
      circuit_t *c2 = circuit_get_by_circid_orconn_impl(c->n_circ_id,
                                                        c->n_conn);
      tor_assert(c == c2);
    }
  }
  if (or_circ && or_circ->p_conn) {
    if (or_circ->p_circ_id) {
      /* ibid */
      circuit_t *c2 = circuit_get_by_circid_orconn_impl(or_circ->p_circ_id,
                                                        or_circ->p_conn);
      tor_assert(c == c2);
    }
  }
#if 0 /* false now that rendezvous exits are attached to p_streams */
  if (origin_circ)
    for (conn = origin_circ->p_streams; conn; conn = conn->next_stream)
      tor_assert(conn->_base.type == CONN_TYPE_AP);
#endif
  if (or_circ)
    for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
      tor_assert(conn->_base.type == CONN_TYPE_EXIT);

  tor_assert(c->deliver_window >= 0);
  tor_assert(c->package_window >= 0);
  if (c->state == CIRCUIT_STATE_OPEN) {
    tor_assert(!c->n_conn_onionskin);
    if (or_circ) {
      tor_assert(or_circ->n_crypto);
      tor_assert(or_circ->p_crypto);
      tor_assert(or_circ->n_digest);
      tor_assert(or_circ->p_digest);
    }
  }
  if (c->state == CIRCUIT_STATE_OR_WAIT && !c->marked_for_close) {
    tor_assert(circuits_pending_or_conns &&
               smartlist_isin(circuits_pending_or_conns, c));
  } else {
    tor_assert(!circuits_pending_or_conns ||
               !smartlist_isin(circuits_pending_or_conns, c));
  }
  if (origin_circ && origin_circ->cpath) {
    assert_cpath_ok(origin_circ->cpath);
  }
  if (c->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED) {
    tor_assert(or_circ);
    if (!c->marked_for_close) {
      tor_assert(or_circ->rend_splice);
      tor_assert(or_circ->rend_splice->rend_splice == or_circ);
    }
    tor_assert(or_circ->rend_splice != or_circ);
  } else {
    tor_assert(!or_circ || !or_circ->rend_splice);
  }
}