Преглед на файлове

Turn tor_strpartion into a swiss-army-knife function, so it can terminate or not-terminate appropriately.

svn:r2429
Nick Mathewson преди 20 години
родител
ревизия
6c970aec94
променени са 4 файла, в които са добавени 57 реда и са изтрити 13 реда
  1. 5 4
      src/common/crypto.c
  2. 36 5
      src/common/util.c
  3. 5 1
      src/common/util.h
  4. 11 3
      src/or/test.c

+ 5 - 4
src/common/crypto.c

@@ -514,9 +514,8 @@ crypto_pk_env_t *crypto_pk_DER64_decode_public_key(const char *in)
   }
   /* base64_decode doesn't work unless we insert linebreaks every 64
    * characters.  how dumb. */
-  if (tor_strpartition(partitioned, sizeof(partitioned), in, "\n", 64))
-    return NULL;
-  if (strlcat(partitioned, "\n",sizeof(partitioned))>=sizeof(partitioned))
+  if (tor_strpartition(partitioned, sizeof(partitioned), in, "\n", 64,
+                       ALWAYS_TERMINATE))
     return NULL;
   len = base64_decode(buf, sizeof(buf), partitioned, strlen(partitioned));
   if (len<0) {
@@ -919,7 +918,9 @@ crypto_pk_get_fingerprint(crypto_pk_env_t *pk, char *fp_out, int add_space)
   }
   base16_encode(hexdigest,sizeof(hexdigest),digest,DIGEST_LEN);
   if (add_space) {
-    tor_strpartition(fp_out, FINGERPRINT_LEN+1, hexdigest, " ", 4);
+    if (tor_strpartition(fp_out, FINGERPRINT_LEN+1, hexdigest, " ", 4,
+                         NEVER_TERMINATE)<0)
+      return -1;
   } else {
     strcpy(fp_out, hexdigest);
   }

+ 36 - 5
src/common/util.c

@@ -219,25 +219,56 @@ int tor_strstrip(char *s, const char *strip)
 /** Set the <b>dest_len</b>-byte buffer <b>buf</b> to contain the
  * string <b>s</b>, with the string <b>insert</b> inserted after every
  * <b>n</b> characters.  Return 0 on success, -1 on failure.
+ *
+ * If <b>rule</b> is ALWAYS_TERMINATE, then always end the string with
+ * <b>insert</b>, even if its length is not a multiple of <b>n</b>.  If
+ * <b>rule</b> is NEVER_TERMINATE, then never end the string with
+ * <b>insert</b>, even if its length <i>is</i> a multiple of <b>n</b>.
+ * If <b>rule</b> is TERMINATE_IF_EVEN, then end the string with <b>insert</b>
+ * exactly when its length <i>is</i> a multiple of <b>n</b>.
  */
 int tor_strpartition(char *dest, size_t dest_len,
-                     const char *s, const char *insert, size_t n)
+                     const char *s, const char *insert, size_t n,
+                     part_finish_rule_t rule)
 {
   tor_assert(s && insert && n > 0);
+  char *destp;
   int len_in, len_out, len_ins;
+  int is_even;
   len_in = strlen(s);
   len_ins = strlen(insert);
   len_out = len_in + (len_in/n)*len_ins;
+  is_even = (len_in%n) == 0;
+  switch(rule)
+    {
+    case ALWAYS_TERMINATE:
+      if (!is_even) len_out += len_ins;
+      break;
+    case NEVER_TERMINATE:
+      if (is_even && len_in) len_out -= len_ins;
+      break;
+    case TERMINATE_IF_EVEN:
+      break;
+    }
   if (dest_len < len_out+1)
     return -1;
+  destp = dest;
   while(len_in) {
-    strncpy(dest, s, n);
+    strncpy(destp, s, n);
     len_in -= n;
-    if (len_in < 0) break;
-    strcpy(dest+n, insert);
+    if (len_in < 0) {
+      if (rule == ALWAYS_TERMINATE)
+        strcpy(destp+n+len_in,insert);
+      break;
+    } else if (len_in == 0 && rule == NEVER_TERMINATE) {
+      *(destp+n) = '\0';
+      break;
+    }
+    strcpy(destp+n, insert);
     s += n;
-    dest += n+len_ins;
+    destp += n+len_ins;
   }
+  tor_assert(len_out == strlen(dest));
   return 0;
 }
 

+ 5 - 1
src/common/util.h

@@ -88,8 +88,12 @@ char *tor_strndup(const char *s, size_t n);
 void tor_strlower(char *s);
 int strcmpstart(const char *s1, const char *s2);
 int tor_strstrip(char *s, const char *strip);
+typedef enum {
+  ALWAYS_TERMINATE, NEVER_TERMINATE, TERMINATE_IF_EVEN
+} part_finish_rule_t;
 int tor_strpartition(char *dest, size_t dest_len,
-                     const char *s, const char *insert, size_t n);
+                     const char *s, const char *insert, size_t n,
+                     part_finish_rule_t rule);
 
 
 /* Some platforms segfault when you try to access a multi-byte type

+ 11 - 3
src/or/test.c

@@ -620,10 +620,18 @@ test_util() {
   test_streq(buf, "Testing123");
 
   /* Test tor_strpartition() */
-  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefg", "##", 3));
+  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefg", "##", 3,
+                                 TERMINATE_IF_EVEN));
   test_streq(buf, "abc##def##g");
-  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefghi", "##", 3));
+  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefg", "##", 3,
+                                 ALWAYS_TERMINATE));
+  test_streq(buf, "abc##def##g##");
+  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefghi", "##", 3,
+                                 TERMINATE_IF_EVEN));
   test_streq(buf, "abc##def##ghi##");
+  test_assert(! tor_strpartition(buf, sizeof(buf), "abcdefghi", "##", 3,
+                                 NEVER_TERMINATE));
+  test_streq(buf, "abc##def##ghi");
 
   /* XXXX test older functions. */
   smartlist_free(sl);
@@ -915,7 +923,7 @@ test_dir_format()
   strcat(buf2, "\n"
          "published 1970-01-01 00:00:00\n"
          "opt fingerprint ");
-  crypto_pk_get_fingerprint(pk2, fingerprint, 1);
+  test_assert(!crypto_pk_get_fingerprint(pk2, fingerprint, 1));
   strcat(buf2, fingerprint);
   strcat(buf2, "\nopt uptime 0\n"
   /* XXX the "0" above is hardcoded, but even if we made it reflect