diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-03-03 18:47:35 +0000 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-03-19 16:08:01 -0700 |
commit | 8070a357fb6e1dc60a65a2281c932f71bbbd65d6 (patch) | |
tree | aed208532182335c9af31ab545b606159f00569c | |
parent | 30333e820ed170e7290045abd3213ea6a5e60efa (diff) | |
download | libgit2-8070a357fb6e1dc60a65a2281c932f71bbbd65d6.tar.gz |
Introduce `git_buf_decode_percent`
Introduce a function to take a percent-encoded string (URI encoded,
described by RFC 1738) and decode it into a `git_buf`.
-rw-r--r-- | src/buffer.c | 32 | ||||
-rw-r--r-- | src/buffer.h | 3 |
2 files changed, 34 insertions, 1 deletions
diff --git a/src/buffer.c b/src/buffer.c index 6dfcbfbe6..8a58d1afa 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -212,7 +212,7 @@ int git_buf_put(git_buf *buf, const char *data, size_t len) size_t new_size; assert(data); - + GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, len); GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1); ENSURE_SIZE(buf, new_size); @@ -455,6 +455,36 @@ on_error: return -1; } +#define HEX_DECODE(c) ((c | 32) % 39 - 9) + +int git_buf_decode_percent( + git_buf *buf, + const char *str, + size_t str_len) +{ + size_t str_pos, new_size; + + GITERR_CHECK_ALLOC_ADD(&new_size, buf->size, str_len); + GITERR_CHECK_ALLOC_ADD(&new_size, new_size, 1); + ENSURE_SIZE(buf, new_size); + + for (str_pos = 0; str_pos < str_len; buf->size++, str_pos++) { + if (str[str_pos] == '%' && + str_len > str_pos + 2 && + isxdigit(str[str_pos + 1]) && + isxdigit(str[str_pos + 2])) { + buf->ptr[buf->size] = (HEX_DECODE(str[str_pos + 1]) << 4) + + HEX_DECODE(str[str_pos + 2]); + str_pos += 2; + } else { + buf->ptr[buf->size] = str[str_pos]; + } + } + + buf->ptr[buf->size] = '\0'; + return 0; +} + int git_buf_vprintf(git_buf *buf, const char *format, va_list ap) { size_t expected_size, new_size; diff --git a/src/buffer.h b/src/buffer.h index b0aece488..cc77fc030 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -190,6 +190,9 @@ int git_buf_encode_base85(git_buf *buf, const char *data, size_t len); /* Decode the given "base85" and write the result to the buffer */ int git_buf_decode_base85(git_buf *buf, const char *base64, size_t len, size_t output_len); +/* Decode the given percent-encoded string and write the result to the buffer */ +int git_buf_decode_percent(git_buf *buf, const char *str, size_t len); + /* * Insert, remove or replace a portion of the buffer. * |