diff options
author | Edward Thomson <ethomson@microsoft.com> | 2014-04-08 17:18:47 -0700 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-05-26 11:36:11 -0500 |
commit | d34f68261ef95b517944d4fa89ee13b4a68d3cb4 (patch) | |
tree | 686b92a0e7174b891bd4e5a61e480acfc1be5002 /src/buffer.c | |
parent | 7cb904ba4443c22ff5396769b7d07a7f329c0102 (diff) | |
download | libgit2-d34f68261ef95b517944d4fa89ee13b4a68d3cb4.tar.gz |
Patch parsing from patch files
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 75 |
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; +} |