]> git.proxmox.com Git - libgit2.git/commitdiff
Add git_buf_unescape and git__unescape to unescape all characters in a string (in...
authoryorah <yoram.harmelin@gmail.com>
Thu, 12 Jul 2012 14:31:59 +0000 (16:31 +0200)
committeryorah <yoram.harmelin@gmail.com>
Tue, 24 Jul 2012 12:03:07 +0000 (14:03 +0200)
src/attr_file.c
src/buffer.c
src/buffer.h
src/util.c
src/util.h
tests-clar/core/buffer.c

index 0dad09727d14d8c5f07a16d75a277587da0e353f..837c42d8e1291e5d223f9492a899e281e2bc36c7 100644 (file)
@@ -426,17 +426,7 @@ int git_attr_fnmatch__parse(
                return -1;
        } else {
                /* strip '\' that might have be used for internal whitespace */
-               char *to = spec->pattern;
-               for (scan = spec->pattern; *scan; to++, scan++) {
-                       if (*scan == '\\')
-                               scan++; /* skip '\' but include next char */
-                       if (to != scan)
-                               *to = *scan;
-               }
-               if (to != scan) {
-                       *to = '\0';
-                       spec->length = (to - spec->pattern);
-               }
+               spec->length = git__unescape(spec->pattern);
        }
 
        return 0;
index 5d54ee1a58e54ac976a398f368f9062b0546dfa7..b57998e1b6b1650cb00d6497de91f59858753e03 100644 (file)
@@ -496,3 +496,7 @@ bool git_buf_is_binary(const git_buf *buf)
        return ((printable >> 7) < nonprintable);
 }
 
+void git_buf_unescape(git_buf *buf)
+{
+       buf->size = git__unescape(buf->ptr);
+}
index 75f3b0e4f8413bb463bb589c072a71fe6f6b3ba3..17922e408ea7811c3dc35e1ca18cf4d9a44f48a9 100644 (file)
@@ -151,4 +151,7 @@ int git_buf_common_prefix(git_buf *buf, const git_strarray *strings);
 /* Check if buffer looks like it contains binary data */
 bool git_buf_is_binary(const git_buf *buf);
 
+/* Unescape all characters in a buffer */
+void git_buf_unescape(git_buf *buf);
+
 #endif
index 3093cd7676cbcfe04f1ca445b20de821a36ad6a9..90bb3d02afdb914c875932f871c33de234458e06 100644 (file)
@@ -435,3 +435,21 @@ int git__parse_bool(int *out, const char *value)
 
        return -1;
 }
+
+size_t git__unescape(char *str)
+{
+       char *scan, *pos = str;
+
+       for (scan = str; *scan; pos++, scan++) {
+               if (*scan == '\\' && *(scan + 1) != '\0')
+                       scan++; /* skip '\' but include next char */
+               if (pos != scan)
+                       *pos = *scan;
+       }
+
+       if (pos != scan) {
+               *pos = '\0';
+       }
+
+       return (pos - str);
+}
index a84dcab1e6e47ade74e84d8f87d881fd53a82136..905fc927ff647ebf0b86da2a353cb7626773f7ed 100644 (file)
@@ -238,4 +238,13 @@ extern int git__parse_bool(int *out, const char *value);
  */
 int git__date_parse(git_time_t *out, const char *date);
 
+/*
+ * Unescapes a string in-place.
+ * 
+ * Edge cases behavior:
+ * - "jackie\" -> "jacky\"
+ * - "chan\\" -> "chan\"
+ */
+extern size_t git__unescape(char *str);
+
 #endif /* INCLUDE_util_h__ */
index 21aaaed7ec640c8c51660300d2a848a248e3a836..b6274b012e289c288490cbb6c5550ad08eb38998 100644 (file)
@@ -658,3 +658,23 @@ void test_core_buffer__puts_escaped(void)
 
        git_buf_free(&a);
 }
+
+static void assert_unescape(char *expected, char *to_unescape) {
+       git_buf buf = GIT_BUF_INIT;
+
+       cl_git_pass(git_buf_sets(&buf, to_unescape));
+       git_buf_unescape(&buf);
+       cl_assert_equal_s(expected, buf.ptr);
+       cl_assert_equal_i(strlen(expected), buf.size);
+
+       git_buf_free(&buf);
+}
+
+void test_core_buffer__unescape(void)
+{
+       assert_unescape("Escaped\\", "Es\\ca\\ped\\");
+       assert_unescape("Es\\caped\\", "Es\\\\ca\\ped\\\\");
+       assert_unescape("\\", "\\");
+       assert_unescape("\\", "\\\\");
+       assert_unescape("", "");
+}