diff --git a/doc/manual/98-acknowledgement.md b/doc/manual/97-acknowledgement.md similarity index 93% rename from doc/manual/98-acknowledgement.md rename to doc/manual/97-acknowledgement.md index 2b66943..3b291e2 100644 --- a/doc/manual/98-acknowledgement.md +++ b/doc/manual/97-acknowledgement.md @@ -20,6 +20,7 @@ Henrique de Carvalho Yihe Lu Eugenio Gigante Mohanad Khaled +Haoran Zhang ``` ## Committers @@ -45,8 +46,4 @@ community. Consider giving the project a [star][star] on [GitHub][pagmoneta] if you find it useful. And, feel free to follow -the project on [Twitter][twitter] as well. - -## License - -[BSD-3-Clause][license] +the project on [Twitter][twitter] as well. \ No newline at end of file diff --git a/doc/manual/98-licenses.md b/doc/manual/98-licenses.md new file mode 100644 index 0000000..1a5916a --- /dev/null +++ b/doc/manual/98-licenses.md @@ -0,0 +1,78 @@ +\newpage + +# License + +``` +Copyright (C) 2024 The pgagroal community + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided +with the distribution. + +3. Neither the name of the copyright holder nor the names of +its contributors may be used to endorse or promote products +derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. +``` + +[BSD-3-Clause][license] + + +## libart +Our adaptive radix tree (ART) implementation is based on + [The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases][ART_paper] + and [libart][libart] which has a [3-BSD license][license] as + +``` +Copyright (c) 2012, Armon Dadgar +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +* Neither the name of the organization nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ARMON DADGAR +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +``` \ No newline at end of file diff --git a/doc/manual/99-references.md b/doc/manual/99-references.md index e0d89ae..5fe684e 100644 --- a/doc/manual/99-references.md +++ b/doc/manual/99-references.md @@ -24,6 +24,8 @@ [prometheus]: https://prometheus.io/ [wireshark]: https://www.wireshark.org/ [pgprtdbg]: https://github.com/jesperpedersen/pgprtdbg + [ART_paper]: http://www-db.in.tum.de/~leis/papers/ART.pdf + [libart]: https://github.com/armon/libart [rpm]: https://github.com/agroal/pgagroal/blob/main/doc/RPM.md diff --git a/src/include/json.h b/src/include/json.h index 20d79ca..21510a0 100644 --- a/src/include/json.h +++ b/src/include/json.h @@ -98,6 +98,15 @@ pgagroal_json_put(struct json* item, char* key, uintptr_t val, enum value_type t uintptr_t pgagroal_json_get(struct json* item, char* tag); +/** + * Check if the json item contains the given key + * @param item The json item + * @param key The key + * @return True if the key exists, otherwise false + */ +bool +pgagroal_json_contains_key(struct json* item, char* key); + /** * Append an entry into the json array * If the entry is put into an empty json object, it will be treated as json array, @@ -192,4 +201,4 @@ pgagroal_json_destroy(struct json* object); } #endif -#endif \ No newline at end of file +#endif diff --git a/src/include/pgagroal.h b/src/include/pgagroal.h index 401cc0b..1580c29 100644 --- a/src/include/pgagroal.h +++ b/src/include/pgagroal.h @@ -178,6 +178,7 @@ extern "C" { #define INDENT_PER_LEVEL 2 #define FORMAT_JSON 0 #define FORMAT_TEXT 1 +#define FORMAT_JSON_COMPACT 2 #define BULLET_POINT "- " #define likely(x) __builtin_expect (!!(x), 1) diff --git a/src/include/utils.h b/src/include/utils.h index 6dd7292..7d0d207 100644 --- a/src/include/utils.h +++ b/src/include/utils.h @@ -464,6 +464,14 @@ pgagroal_indent(char* str, char* tag, int indent); bool pgagroal_compare_string(const char* str1, const char* str2); +/** +* Escape a string +* @param str The original string +* @return The escaped string +*/ +char* +pgagroal_escape_string(char* str); + #ifdef DEBUG /** diff --git a/src/include/value.h b/src/include/value.h index a443d5b..40c460c 100644 --- a/src/include/value.h +++ b/src/include/value.h @@ -26,7 +26,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #ifndef PGAGROAL_VALUE_H #define PGAGROAL_VALUE_H @@ -59,7 +58,7 @@ enum value_type { ValueDeque, ValueART, ValueRef, - ValueVerifyEntry, + ValueMem, }; /** diff --git a/src/libpgagroal/art.c b/src/libpgagroal/art.c index f6790eb..063ca37 100644 --- a/src/libpgagroal/art.c +++ b/src/libpgagroal/art.c @@ -27,6 +27,7 @@ */ #include +#include #include #include @@ -292,9 +293,15 @@ art_to_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, s static int art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value); +static int +art_to_compact_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value); + static char* to_json_string(struct art* t, char* tag, int indent); +static char* +to_compact_json_string(struct art* t, char* tag, int indent); + static char* to_text_string(struct art* t, char* tag, int indent); @@ -382,6 +389,10 @@ pgagroal_art_to_string(struct art* t, int32_t format, char* tag, int indent) { return to_text_string(t, tag, indent); } + else if (format == FORMAT_JSON_COMPACT) + { + return to_compact_json_string(t, tag, indent); + } return NULL; } @@ -1459,10 +1470,13 @@ art_to_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, s struct to_string_param* p = (struct to_string_param*) param; char* str = NULL; char* tag = NULL; + char* translated_key = NULL; p->cnt++; bool has_next = p->cnt < p->t->size; tag = pgagroal_append_char(tag, '"'); - tag = pgagroal_append(tag, (char*)key); + translated_key = pgagroal_escape_string((char*)key); + tag = pgagroal_append(tag, translated_key); + free(translated_key); tag = pgagroal_append_char(tag, '"'); tag = pgagroal_append(tag, ": "); str = pgagroal_value_to_string(value, FORMAT_JSON, tag, p->indent); @@ -1474,6 +1488,30 @@ art_to_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, s return 0; } +static int +art_to_compact_json_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value) +{ + struct to_string_param* p = (struct to_string_param*) param; + char* str = NULL; + char* tag = NULL; + char* translated_key = NULL; + p->cnt++; + bool has_next = p->cnt < p->t->size; + tag = pgagroal_append_char(tag, '"'); + translated_key = pgagroal_escape_string((char*)key); + tag = pgagroal_append(tag, (char*)translated_key); + free(translated_key); + tag = pgagroal_append_char(tag, '"'); + tag = pgagroal_append(tag, ":"); + str = pgagroal_value_to_string(value, FORMAT_JSON_COMPACT, tag, p->indent); + free(tag); + p->str = pgagroal_append(p->str, str); + p->str = pgagroal_append(p->str, has_next ? "," : ""); + + free(str); + return 0; +} + static int art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, struct value* value) { @@ -1484,7 +1522,7 @@ art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, s bool has_next = p->cnt < p->t->size; tag = pgagroal_append(tag, (char*)key); tag = pgagroal_append(tag, ": "); - if (value->type == ValueJSON) + if (value->type == ValueJSON && ((struct json*) value->data)->type != JSONUnknown) { tag = pgagroal_append(tag, "\n"); } @@ -1492,7 +1530,15 @@ art_to_text_string_cb(void* param, const unsigned char* key, uint32_t key_len, s { if (p->cnt == 1) { - str = pgagroal_value_to_string(value, FORMAT_TEXT, tag, 0); + if (value->type != ValueJSON || ((struct json*) value->data)->type == JSONUnknown) + { + str = pgagroal_value_to_string(value, FORMAT_TEXT, tag, 0); + } + else + { + p->str = pgagroal_indent(p->str, tag, 0); + str = pgagroal_value_to_string(value, FORMAT_TEXT, NULL, p->indent + INDENT_PER_LEVEL); + } } else { @@ -1535,6 +1581,29 @@ to_json_string(struct art* t, char* tag, int indent) return ret; } +static char* +to_compact_json_string(struct art* t, char* tag, int indent) +{ + char* ret = NULL; + ret = pgagroal_indent(ret, tag, indent); + if (t == NULL || t->size == 0) + { + ret = pgagroal_append(ret, "{}"); + return ret; + } + ret = pgagroal_append(ret, "{"); + struct to_string_param param = { + .indent = indent, + .str = ret, + .t = t, + .cnt = 0, + }; + art_iterate(t, art_to_compact_json_string_cb, ¶m); + ret = param.str; + ret = pgagroal_append(ret, "}"); + return ret; +} + static char* to_text_string(struct art* t, char* tag, int indent) { diff --git a/src/libpgagroal/deque.c b/src/libpgagroal/deque.c index 37e436f..ee84d1b 100644 --- a/src/libpgagroal/deque.c +++ b/src/libpgagroal/deque.c @@ -64,6 +64,9 @@ deque_find(struct deque* deque, char* tag); static char* to_json_string(struct deque* deque, char* tag, int indent); +static char* +to_compact_json_string(struct deque* deque, char* tag, int indent); + static char* to_text_string(struct deque* deque, char* tag, int indent); @@ -229,6 +232,10 @@ pgagroal_deque_to_string(struct deque* deque, int32_t format, char* tag, int ind { return to_text_string(deque, tag, indent); } + else if (format == FORMAT_JSON_COMPACT) + { + return to_compact_json_string(deque, tag, indent); + } return NULL; } @@ -462,6 +469,42 @@ to_json_string(struct deque* deque, char* tag, int indent) return ret; } +static char* +to_compact_json_string(struct deque* deque, char* tag, int indent) +{ + char* ret = NULL; + ret = pgagroal_indent(ret, tag, indent); + struct deque_node* cur = NULL; + if (deque == NULL || pgagroal_deque_empty(deque)) + { + ret = pgagroal_append(ret, "[]"); + return ret; + } + deque_read_lock(deque); + ret = pgagroal_append(ret, "["); + cur = deque_next(deque, deque->start); + while (cur != NULL) + { + bool has_next = cur->next != deque->end; + char* str = NULL; + char* t = NULL; + if (cur->tag != NULL) + { + t = pgagroal_append(t, cur->tag); + t = pgagroal_append(t, ":"); + } + str = pgagroal_value_to_string(cur->data, FORMAT_JSON_COMPACT, t, indent); + free(t); + ret = pgagroal_append(ret, str); + ret = pgagroal_append(ret, has_next ? "," : ""); + free(str); + cur = deque_next(deque, cur); + } + ret = pgagroal_append(ret, "]"); + deque_unlock(deque); + return ret; +} + static char* to_text_string(struct deque* deque, char* tag, int indent) { diff --git a/src/libpgagroal/json.c b/src/libpgagroal/json.c index 9376351..3782880 100644 --- a/src/libpgagroal/json.c +++ b/src/libpgagroal/json.c @@ -46,6 +46,7 @@ static int parse_string(char* str, uint64_t* index, struct json** obj); static int json_add(struct json* obj, char* key, uintptr_t val, enum value_type type); static int fill_value(char* str, char* key, uint64_t* index, struct json* o); static bool value_start(char ch); +static int handle_escape_char(char* str, uint64_t* index, uint64_t len, char* ch); int pgagroal_json_append(struct json* array, uintptr_t entry, enum value_type type) @@ -117,10 +118,7 @@ pgagroal_json_to_string(struct json* object, int32_t format, char* tag, int inde if (object == NULL || (object->type == JSONUnknown || object->elements == NULL)) { str = pgagroal_indent(str, tag, indent); - if (format == FORMAT_JSON) - { - str = pgagroal_append(str, "{}"); - } + str = pgagroal_append(str, "{}"); return str; } if (object->type != JSONArray) @@ -163,6 +161,16 @@ pgagroal_json_get(struct json* item, char* tag) return pgagroal_art_search(item->elements, (unsigned char*)tag, strlen(tag) + 1); } +bool +pgagroal_json_contains_key(struct json* item, char* key) +{ + if (item == NULL || item->type != JSONItem || key == NULL || strlen(key) == 0) + { + return false; + } + return pgagroal_art_contains_key(item->elements, (unsigned char*)key, strlen(key) + 1); +} + int pgagroal_json_iterator_create(struct json* object, struct json_iterator** iter) { @@ -325,6 +333,18 @@ parse_string(char* str, uint64_t* index, struct json** obj) // The key while (idx < len && str[idx] != '"') { + char ec_ch; + // handle escape character + if (str[idx] == '\\') + { + if (handle_escape_char(str, &idx, len, &ec_ch)) + { + goto error; + } + key = pgagroal_append_char(key, ec_ch); + continue; + } + key = pgagroal_append_char(key, str[idx++]); } if (idx == len || key == NULL) @@ -443,6 +463,17 @@ fill_value(char* str, char* key, uint64_t* index, struct json* o) idx++; while (idx < len && str[idx] != '"') { + char ec_ch; + if (str[idx] == '\\') + { + if (handle_escape_char(str, &idx, len, &ec_ch)) + { + goto error; + } + val = pgagroal_append_char(val, ec_ch); + continue; + } + val = pgagroal_append_char(val, str[idx++]); } if (idx == len) @@ -549,6 +580,38 @@ fill_value(char* str, char* key, uint64_t* index, struct json* o) return 1; } +static int +handle_escape_char(char* str, uint64_t* index, uint64_t len, char* ch) +{ + uint64_t idx = *index; + idx++; + if (idx == len) // security check + { + return 1; + } + // Check the next character after checking '\' character + switch (str[idx]) + { + case '\"': + case '\\': + *ch = str[idx]; + break; + case 'n': + *ch = '\n'; + break; + case 't': + *ch = '\t'; + break; + case 'r': + *ch = '\r'; + break; + default: + return 1; + } + *index = idx + 1; + return 0; +} + static bool type_allowed(enum value_type type) { diff --git a/src/libpgagroal/utils.c b/src/libpgagroal/utils.c index 420810c..062b5c4 100644 --- a/src/libpgagroal/utils.c +++ b/src/libpgagroal/utils.c @@ -1164,3 +1164,62 @@ pgagroal_compare_string(const char* str1, const char* str2) } return strcmp(str1, str2) == 0; } + +char* +pgagroal_escape_string(char* str) +{ + if (str == NULL) + { + return NULL; + } + + char* translated_ec_string = NULL; + int len = 0; + int idx = 0; + size_t translated_len = 0; + + len = strlen(str); + for (int i = 0; i < len; i++) + { + if (str[i] == '\"' || str[i] == '\\' || str[i] == '\n' || str[i] == '\t' || str[i] == '\r') + { + translated_len++; + } + translated_len++; + } + translated_ec_string = (char*)malloc(translated_len + 1); + + for (int i = 0; i < len; i++, idx++) + { + switch (str[i]) + { + case '\\': + case '\"': + translated_ec_string[idx] = '\\'; + idx++; + translated_ec_string[idx] = str[i]; + break; + case '\n': + translated_ec_string[idx] = '\\'; + idx++; + translated_ec_string[idx] = 'n'; + break; + case '\t': + translated_ec_string[idx] = '\\'; + idx++; + translated_ec_string[idx] = 't'; + break; + case '\r': + translated_ec_string[idx] = '\\'; + idx++; + translated_ec_string[idx] = 'r'; + break; + default: + translated_ec_string[idx] = str[i]; + break; + } + } + translated_ec_string[idx] = '\0'; // terminator + + return translated_ec_string; +} \ No newline at end of file diff --git a/src/libpgagroal/value.c b/src/libpgagroal/value.c index da823fd..b9e3375 100644 --- a/src/libpgagroal/value.c +++ b/src/libpgagroal/value.c @@ -61,6 +61,7 @@ static char* bool_to_string_cb(uintptr_t data, int32_t format, char* tag, int in static char* deque_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent); static char* art_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent); static char* json_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent); +static char* mem_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent); int pgagroal_value_create(enum value_type type, uintptr_t data, struct value** value) @@ -126,6 +127,9 @@ pgagroal_value_create(enum value_type type, uintptr_t data, struct value** value case ValueART: val->to_string = art_to_string_cb; break; + case ValueMem: + val->to_string = mem_to_string_cb; + break; default: val->to_string = noop_to_string_cb; break; @@ -144,6 +148,10 @@ pgagroal_value_create(enum value_type type, uintptr_t data, struct value** value val->destroy_data = free_destroy_cb; break; } + case ValueMem: + val->data = data; + val->destroy_data = free_destroy_cb; + break; case ValueJSON: val->data = data; val->destroy_data = json_destroy_cb; @@ -292,8 +300,9 @@ static char* int8_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRId8, (int8_t)data); ret = pgagroal_append(ret, buf); @@ -304,8 +313,8 @@ static char* uint8_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRIu8, (uint8_t)data); ret = pgagroal_append(ret, buf); @@ -316,8 +325,9 @@ static char* int16_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRId16, (int16_t)data); ret = pgagroal_append(ret, buf); @@ -328,8 +338,9 @@ static char* uint16_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRIu16, (uint16_t)data); ret = pgagroal_append(ret, buf); @@ -340,8 +351,9 @@ static char* int32_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRId32, (int32_t)data); ret = pgagroal_append(ret, buf); @@ -352,8 +364,9 @@ static char* uint32_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRIu32, (uint32_t)data); ret = pgagroal_append(ret, buf); @@ -364,8 +377,9 @@ static char* int64_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRId64, (int64_t)data); ret = pgagroal_append(ret, buf); @@ -376,8 +390,9 @@ static char* uint64_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%" PRIu64, (uint64_t)data); ret = pgagroal_append(ret, buf); @@ -388,8 +403,9 @@ static char* float_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%f", pgagroal_value_to_float(data)); ret = pgagroal_append(ret, buf); @@ -400,11 +416,13 @@ static char* double_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "%f", pgagroal_value_to_double(data)); ret = pgagroal_append(ret, buf); + return ret; } @@ -412,20 +430,22 @@ static char* string_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char* str = (char*) data; char buf[MISC_LENGTH]; + char* translated_string = NULL; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); if (str == NULL) { - if (format == FORMAT_JSON) + if (format == FORMAT_JSON || format == FORMAT_JSON_COMPACT) { snprintf(buf, MISC_LENGTH, "null"); } } else if (strlen(str) == 0) { - if (format == FORMAT_JSON) + if (format == FORMAT_JSON || format == FORMAT_JSON_COMPACT) { snprintf(buf, MISC_LENGTH, "\"%s\"", str); } @@ -436,9 +456,11 @@ string_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) } else { - if (format == FORMAT_JSON) + if (format == FORMAT_JSON || format == FORMAT_JSON_COMPACT) { - snprintf(buf, MISC_LENGTH, "\"%s\"", str); + translated_string = pgagroal_escape_string(str); + snprintf(buf, MISC_LENGTH, "\"%s\"", translated_string); + free(translated_string); } else if (format == FORMAT_TEXT) { @@ -453,8 +475,8 @@ static char* bool_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); bool val = (bool) data; + ret = pgagroal_indent(ret, tag, indent); ret = pgagroal_append(ret, val?"true":"false"); return ret; } @@ -463,11 +485,13 @@ static char* char_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { char* ret = NULL; - ret = pgagroal_indent(ret, tag, indent); char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); memset(buf, 0, MISC_LENGTH); snprintf(buf, MISC_LENGTH, "'%c'", (char)data); ret = pgagroal_append(ret, buf); + return ret; } @@ -487,4 +511,18 @@ static char* json_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) { return pgagroal_json_to_string((struct json*)data, format, tag, indent); +} + +static char* +mem_to_string_cb(uintptr_t data, int32_t format, char* tag, int indent) +{ + char* ret = NULL; + char buf[MISC_LENGTH]; + + ret = pgagroal_indent(ret, tag, indent); + memset(buf, 0, MISC_LENGTH); + snprintf(buf, MISC_LENGTH, "%p", (void*)data); + ret = pgagroal_append(ret, buf); + + return ret; } \ No newline at end of file diff --git a/src/vault.c b/src/vault.c index 4c8313d..04cf58c 100644 --- a/src/vault.c +++ b/src/vault.c @@ -316,7 +316,7 @@ is_ssl_request(int client_fd) static int get_connection_state(struct vault_configuration* config, int client_fd) -{ +{ if (config->common.tls) { if (is_ssl_request(client_fd))