summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2018-03-03 18:47:35 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2018-03-19 16:08:01 -0700
commit8070a357fb6e1dc60a65a2281c932f71bbbd65d6 (patch)
treeaed208532182335c9af31ab545b606159f00569c
parent30333e820ed170e7290045abd3213ea6a5e60efa (diff)
downloadlibgit2-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.c32
-rw-r--r--src/buffer.h3
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.
*