summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7ee46a4)
raw | patch | inline | side by side (parent: 7ee46a4)
author | Sebastian Harl <sh@tokkee.org> | |
Sat, 7 Mar 2015 13:01:17 +0000 (14:01 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sat, 7 Mar 2015 13:01:17 +0000 (14:01 +0100) |
That is, behave as documented, even if the buffer is NULL or otherwise too
small. Return size_t instead of an integer.
small. Return size_t instead of an integer.
diff --git a/src/core/data.c b/src/core/data.c
index 9f2b506fbc1b76e66dd330be7879655a530871ba..914946fbec6761d3e7b4345742ddbd63668106c1 100644 (file)
--- a/src/core/data.c
+++ b/src/core/data.c
CMP_NULL(d1, d2);
- if (sdb_data_format(d1, d1_str, sizeof(d1_str), SDB_UNQUOTED) < 0)
+ if (! sdb_data_format(d1, d1_str, sizeof(d1_str), SDB_UNQUOTED))
return SDB_CMP(sizeof(d1_str), sizeof(d2_str));
- if (sdb_data_format(d2, d2_str, sizeof(d2_str), SDB_UNQUOTED) < 0)
+ if (! sdb_data_format(d2, d2_str, sizeof(d2_str), SDB_UNQUOTED))
return SDB_CMP(sizeof(d1_str), sizeof(d2_str));
return strcasecmp(d1_str, d2_str);
return 0;
} /* sdb_data_strlen */
-int
+size_t
sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted)
{
char tmp[sdb_data_strlen(datum) + 1];
char *data = NULL;
bool is_null = 0;
- int ret = -1;
+ size_t ret = 0;
size_t i, pos;
- if ((! datum) || (! buf) || (! buflen))
- return -1;
+ if (! datum)
+ return 0;
if (datum->type == SDB_TYPE_NULL) {
strncpy(buf, "NULL", buflen);
@@ -1005,37 +1005,41 @@ sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted)
}
else if (datum->type & SDB_TYPE_ARRAY) {
ret = 1;
- buf[0] = '[';
+ if (buflen > 0)
+ buf[0] = '[';
for (i = 0; i < datum->data.array.length; ++i) {
sdb_data_t v = SDB_DATA_INIT;
- int n;
- if ((size_t)ret >= buflen - 1)
- break;
+ size_t n;
if (ret > 1) {
- buf[ret] = ',';
- buf[ret + 1] = ' ';
+ if (buflen > ret + 1) {
+ buf[ret] = ',';
+ buf[ret + 1] = ' ';
+ }
ret += 2;
}
sdb_data_array_get(datum, i, &v);
- n = sdb_data_format(&v, buf + ret, buflen - ret, quoted);
+ if (buflen > ret)
+ n = sdb_data_format(&v, buf + ret, buflen - ret, quoted);
+ else
+ n = sdb_data_format(&v, NULL, 0, quoted);
if (n > 0)
ret += n;
else
break;
}
- if ((size_t)ret < buflen - 1) {
+ if (buflen > ret + 1) {
buf[ret] = ']';
buf[ret + 1] = '\0';
- ++ret;
}
+ ++ret;
}
if (is_null) {
/* never quote NULL */
strncpy(buf, "NULL", buflen);
- ret = (int)SDB_MIN(buflen, 4);
+ ret = 4;
}
else if (data) {
if (quoted == SDB_UNQUOTED)
@@ -1045,7 +1049,8 @@ sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted)
else
ret = snprintf(buf, buflen, "\"%s\"", data);
}
- buf[buflen - 1] = '\0';
+ if (buflen > 0)
+ buf[buflen - 1] = '\0';
return ret;
} /* sdb_data_format */
diff --git a/src/core/store_json.c b/src/core/store_json.c
index f5be74543f32ed8bbee35b2cff6f95dba828d2e1..a772dc39c8f67549c8205a0f63527672b6edf473 100644 (file)
--- a/src/core/store_json.c
+++ b/src/core/store_json.c
if (obj->type == SDB_ATTRIBUTE) {
char tmp[sdb_data_strlen(&ATTR(obj)->value) + 1];
char val[2 * sizeof(tmp) + 3];
- if (sdb_data_format(&ATTR(obj)->value, tmp, sizeof(tmp),
- SDB_DOUBLE_QUOTED) < 0)
+ if (! sdb_data_format(&ATTR(obj)->value, tmp, sizeof(tmp),
+ SDB_DOUBLE_QUOTED))
snprintf(tmp, sizeof(tmp), "<error>");
if (tmp[0] == '"') {
index 5aa69152f237576cb4d2995e15c9a3c771b5b976..2e73780fbf8da67f51c7e040470d051668b20621 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
else if (re->type != SDB_TYPE_REGEX)
return 0;
- if (sdb_data_format(v, value, sizeof(value), SDB_UNQUOTED) < 0)
+ if (! sdb_data_format(v, value, sizeof(value), SDB_UNQUOTED))
status = 0;
else if (! regexec(&re->data.re.regex, value, 0, NULL, 0))
status = 1;
index c037fb00e2a1f8f91ea09d057b7a5064be2f91ca..e529fb9ceec24749aca3efdf8841bbc2dd073e23 100644 (file)
--- a/src/include/core/data.h
+++ b/src/include/core/data.h
};
#define SDB_TYPE_TO_STRING(t) \
- (((t) == SDB_TYPE_INTEGER) ? "INTEGER" \
+ (((t) == SDB_TYPE_NULL) ? "NULL" \
+ : ((t) == SDB_TYPE_INTEGER) ? "INTEGER" \
: ((t) == SDB_TYPE_DECIMAL) ? "DECIMAL" \
: ((t) == SDB_TYPE_STRING) ? "STRING" \
: ((t) == SDB_TYPE_DATETIME) ? "DATETIME" \
* - the number of characters written to the buffer (excluding the terminated
* null byte) or the number of characters which would have been written in
* case the output was truncated
- * - a negative value else
*/
-int
+size_t
sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted);
/*
index 71dae2acbb65f673d011d935e562eba65243a495..cd76dff1c458f53994c7cff1383a9c14c5dd8115 100644 (file)
--- a/t/unit/core/data_test.c
+++ b/t/unit/core/data_test.c
sdb_data_t datum;
const char *expected;
} golden_data[] = {
+ {
+ { SDB_TYPE_NULL, { .integer = 0 } },
+ "NULL",
+ },
{
{ SDB_TYPE_INTEGER, { .integer = 4711 } },
"4711",
for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
sdb_data_t *datum = &golden_data[i].datum;
char buf[sdb_data_strlen(datum) + 2];
- int check;
+ size_t check_null, check;
memset(buf, (int)'A', sizeof(buf));
+ check_null = sdb_data_format(datum, NULL, 0, SDB_DOUBLE_QUOTED);
check = sdb_data_format(datum, buf, sizeof(buf) - 1,
SDB_DOUBLE_QUOTED);
fail_unless(check > 0,
"sdb_data_format(type=%s) used wrong format: %s; expected: %s",
SDB_TYPE_TO_STRING(datum->type), buf, golden_data[i].expected);
- fail_unless((size_t)check <= sizeof(buf) - 2,
+ fail_unless(check_null == check,
+ "sdb_data_format(type=%s, NULL) = %d; "
+ "expected %d (matching sdb_data_format(type=%s, <buf>))",
+ SDB_TYPE_TO_STRING(datum->type), check_null,
+ check, SDB_TYPE_TO_STRING(datum->type));
+ fail_unless(check == strlen(golden_data[i].expected),
+ "sdb_data_format(type=%s) = %d; expected %zu (strlen)",
+ SDB_TYPE_TO_STRING(datum->type), check,
+ strlen(golden_data[i].expected));
+
+ fail_unless(check <= sizeof(buf) - 2,
"sdb_data_format(type=%s) wrote %d bytes; "
"expected <= %zu based on sdb_data_strlen()",
SDB_TYPE_TO_STRING(datum->type), check, sizeof(buf) - 2);
index 01b63502bd5bab44c68cbcea7c6f5577fd63a418..e7e8d44cca4730959a5cccbf720e3298d5adc345 100644 (file)
sdb_data_t datum = SDB_DATA_INIT;
ssize_t check;
- if (sdb_data_format(&golden_data[i].datum, v1, sizeof(v1), 0) < 0)
+ if (! sdb_data_format(&golden_data[i].datum, v1, sizeof(v1), 0))
snprintf(v1, sizeof(v1), "<ERR>");
fail_unless(len == golden_data[i].expected_len,
}
check = sdb_proto_unmarshal_data(buf, len, &datum);
- if (sdb_data_format(&datum, v2, sizeof(v2), 0) < 0)
+ if (! sdb_data_format(&datum, v2, sizeof(v2), 0))
snprintf(v2, sizeof(v2), "<ERR>");
if (sdb_data_isnull(&golden_data[i].datum))
pos, (int)buf[pos], (int)golden_data[i].expected[pos]);
}
- if (sdb_data_format(&golden_data[i].attr.value, v1, sizeof(v1), 0) < 0)
+ if (! sdb_data_format(&golden_data[i].attr.value, v1, sizeof(v1), 0))
snprintf(v1, sizeof(v1), "<ERR>");
check = sdb_proto_unmarshal_attribute(buf, len, &attr);
"<%zu> sdb_proto_unmarshal_attribute(buf<%s>) = %zi; expected: %zi",
i, golden_data[i].attr.key, check, len);
- if (sdb_data_format(&attr.value, v2, sizeof(v2), 0) < 0)
+ if (! sdb_data_format(&attr.value, v2, sizeof(v2), 0))
snprintf(v2, sizeof(v2), "<ERR>");
fail_unless((attr.last_update == golden_data[i].attr.last_update)
&& (attr.parent_type == golden_data[i].attr.parent_type)