Commit efb8a09f authored by nils's avatar nils Committed by Nick Mathewson
Browse files

Fix tor_strtok_r_impl and test cases per bug #5091

==

Nick here. I tweaked this patch a little to make it apply cleanly to
master, to extract some common code into a function, and to replace
snprintf with tor_snprintf.

-- nickm
parent 56e0959d
Loading
Loading
Loading
Loading

changes/bug5091

0 → 100644
+4 −0
Original line number Diff line number Diff line
  o Minor bugfixes:
    - Make our replacement implementation of strtok_r compatible with
      the standard behavior of strtok_r. Patch by nils. Fixes bug
      5091; bugfix on 0.2.2.1-alpha.
+24 −6
Original line number Diff line number Diff line
@@ -546,25 +546,43 @@ const char TOR_TOLOWER_TABLE[256] = {
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
};

/** Helper for tor_strtok_r_impl: Advances cp past all characters in
 * <b>sep</b>, and returns its new value. */
static char *
strtok_helper(char *cp, const char *sep)
{
  if (sep[1]) {
    while (*cp && strchr(sep, *cp))
      ++cp;
  } else {
    while (*cp && *cp == *sep)
      ++cp;
  }
  return cp;
}

/** Implementation of strtok_r for platforms whose coders haven't figured out
 * how to write one.  Hey guys!  You can use this code here for free! */
char *
tor_strtok_r_impl(char *str, const char *sep, char **lasts)
{
  char *cp, *start;
  if (str)
  tor_assert(*sep);
  if (str) {
    str = strtok_helper(str, sep);
    if (!*str)
      return NULL;
    start = cp = *lasts = str;
  else if (!*lasts)
  } else if (!*lasts || !**lasts) {
    return NULL;
  else
  } else {
    start = cp = *lasts;
  }

  tor_assert(*sep);
  if (sep[1]) {
    while (*cp && !strchr(sep, *cp))
      ++cp;
  } else {
    tor_assert(strlen(sep) == 1);
    cp = strchr(cp, *sep);
  }

@@ -572,7 +590,7 @@ tor_strtok_r_impl(char *str, const char *sep, char **lasts)
    *lasts = NULL;
  } else {
    *cp++ = '\0';
    *lasts = cp;
    *lasts = strtok_helper(cp, sep);
  }
  return start;
}
+46 −24
Original line number Diff line number Diff line
@@ -1735,9 +1735,33 @@ test_util_strtok(void)
{
  char buf[128];
  char buf2[128];
  int i;
  char *cp1, *cp2;
  strlcpy(buf, "Graved on the dark in gestures of descent", sizeof(buf));
  strlcpy(buf2, "they.seemed;their!own;most.perfect;monument", sizeof(buf2));

  for (i = 0; i < 3; i++) {
    const char *pad1, *pad2;
    switch (i) {
    case 0:
      pad1 = pad2 = "";
      break;
    case 1:
      pad1 = " ";
      pad2 = "!";
      break;
    case 2:
      pad1 = "  ";
      pad2 = ";!";
      break;
    }
    tor_snprintf(buf, sizeof(buf), "%s", pad1);
    tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
    test_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
    test_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));

    tor_snprintf(buf, sizeof(buf),
                 "%sGraved on the dark  in gestures of descent%s", pad1, pad1);
    tor_snprintf(buf2, sizeof(buf2),
                 "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
    /*  -- "Year's End", Richard Wilbur */

    test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
@@ -1759,8 +1783,8 @@ test_util_strtok(void)
    test_streq("monument", S2());
    test_eq_ptr(NULL, S1());
    test_eq_ptr(NULL, S2());
  }

#if 0
  buf[0] = 0;
  test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
  test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1));
@@ -1773,12 +1797,10 @@ test_util_strtok(void)
  test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
  strlcpy(buf, "  ", sizeof(buf));
  test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
#endif

  strlcpy(buf, "something  ", sizeof(buf));
  test_streq("something", tor_strtok_r_impl(buf, " ", &cp1));
  test_streq(" ", tor_strtok_r_impl(NULL, ";", &cp1));
  test_eq_ptr(NULL, tor_strtok_r_impl(NULL, " ", &cp1));
  test_eq_ptr(NULL, tor_strtok_r_impl(NULL, ";", &cp1));
 done:
  ;
}