summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2014-04-08 17:18:47 -0700
committerEdward Thomson <ethomson@github.com>2016-05-26 11:36:11 -0500
commitd34f68261ef95b517944d4fa89ee13b4a68d3cb4 (patch)
tree686b92a0e7174b891bd4e5a61e480acfc1be5002 /src/buffer.c
parent7cb904ba4443c22ff5396769b7d07a7f329c0102 (diff)
downloadlibgit2-d34f68261ef95b517944d4fa89ee13b4a68d3cb4.tar.gz
Patch parsing from patch files
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 1a5809cca..5fafe69cb 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -766,3 +766,78 @@ int git_buf_splice(
buf->ptr[buf->size] = '\0';
return 0;
}
+
+/* Unquote per http://marc.info/?l=git&m=112927316408690&w=2 */
+int git_buf_unquote(git_buf *buf)
+{
+ size_t i, j;
+ char ch;
+
+ git_buf_rtrim(buf);
+
+ if (buf->size < 2 || buf->ptr[0] != '"' || buf->ptr[buf->size-1] != '"')
+ goto invalid;
+
+ for (i = 0, j = 1; j < buf->size-1; i++, j++) {
+ ch = buf->ptr[j];
+
+ if (ch == '\\') {
+ if (j == buf->size-2)
+ goto invalid;
+
+ ch = buf->ptr[++j];
+
+ switch (ch) {
+ /* \" or \\ simply copy the char in */
+ case '"': case '\\':
+ break;
+
+ /* add the appropriate escaped char */
+ case 'a': ch = '\a'; break;
+ case 'b': ch = '\b'; break;
+ case 'f': ch = '\f'; break;
+ case 'n': ch = '\n'; break;
+ case 'r': ch = '\r'; break;
+ case 't': ch = '\t'; break;
+ case 'v': ch = '\v'; break;
+
+ /* \xyz digits convert to the char*/
+ case '0': case '1': case '2':
+ if (j == buf->size-3) {
+ giterr_set(GITERR_INVALID,
+ "Truncated quoted character \\%c", ch);
+ return -1;
+ }
+
+ if (buf->ptr[j+1] < '0' || buf->ptr[j+1] > '7' ||
+ buf->ptr[j+2] < '0' || buf->ptr[j+2] > '7') {
+ giterr_set(GITERR_INVALID,
+ "Truncated quoted character \\%c%c%c",
+ buf->ptr[j], buf->ptr[j+1], buf->ptr[j+2]);
+ return -1;
+ }
+
+ ch = ((buf->ptr[j] - '0') << 6) |
+ ((buf->ptr[j+1] - '0') << 3) |
+ (buf->ptr[j+2] - '0');
+ j += 2;
+ break;
+
+ default:
+ giterr_set(GITERR_INVALID, "Invalid quoted character \\%c", ch);
+ return -1;
+ }
+ }
+
+ buf->ptr[i] = ch;
+ }
+
+ buf->ptr[i] = '\0';
+ buf->size = i;
+
+ return 0;
+
+invalid:
+ giterr_set(GITERR_INVALID, "Invalid quoted line");
+ return -1;
+}