Code

data: Let sdb_data_parse() accept a const string and copy it if necessary.
authorSebastian Harl <sh@tokkee.org>
Fri, 2 Jan 2015 14:47:24 +0000 (15:47 +0100)
committerSebastian Harl <sh@tokkee.org>
Fri, 2 Jan 2015 14:47:24 +0000 (15:47 +0100)
Given that we need a copy for regex values anyway, this is more consistent.

src/core/data.c
src/include/core/data.h
src/utils/unixsock.c
t/unit/core/data_test.c

index 8c54c9390842f0014df803009af11358fe6fbc76..d34a4dd711250041cd26d463575535bd70522f4a 100644 (file)
@@ -1042,12 +1042,17 @@ sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted)
 } /* sdb_data_format */
 
 int
-sdb_data_parse(char *str, int type, sdb_data_t *data)
+sdb_data_parse(const char *str, int type, sdb_data_t *data)
 {
        sdb_data_t tmp;
 
        char *endptr = NULL;
 
+       if (! str) {
+               errno = EINVAL;
+               return -1;
+       }
+
        errno = 0;
        if (type == SDB_TYPE_INTEGER) {
                tmp.data.integer = strtoll(str, &endptr, 0);
@@ -1056,16 +1061,20 @@ sdb_data_parse(char *str, int type, sdb_data_t *data)
                tmp.data.decimal = strtod(str, &endptr);
        }
        else if (type == SDB_TYPE_STRING) {
-               tmp.data.string = str;
+               tmp.data.string = strdup(str);
+               if (! tmp.data.string)
+                       return -1;
        }
        else if (type == SDB_TYPE_DATETIME) {
                double datetime = strtod(str, &endptr);
                tmp.data.datetime = DOUBLE_TO_SDB_TIME(datetime);
        }
        else if (type == SDB_TYPE_BINARY) {
-               /* we don't support any binary information containing 0-bytes */
+               /* we don't support any binary information containing 0-bytes here */
+               tmp.data.binary.datum = (unsigned char *)strdup(str);
+               if (! tmp.data.binary.datum)
+                       return -1;
                tmp.data.binary.length = strlen(str);
-               tmp.data.binary.datum = (unsigned char *)str;
        }
        else if (type == SDB_TYPE_REGEX) {
                tmp.data.re.raw = strdup(str);
index c179fea84b142f836a24eb4791eb12194344f12e..c037fb00e2a1f8f91ea09d057b7a5064be2f91ca 100644 (file)
@@ -302,24 +302,16 @@ sdb_data_format(const sdb_data_t *datum, char *buf, size_t buflen, int quoted);
  * character of the string is "0"), sedecimal (base 16, if the string includes
  * the "0x" prefix), or decimal. Decimal numbers may also be "infinity" or
  * "NaN" or may use a decimal exponent. Date-time values are expected to be
- * specified as (floating point) number of seconds since the epoch. For string
- * and binary data, the input string is passed to the datum. The function does
- * not allocate new memory for that purpose. Use sdb_data_copy() if you want
- * to do that. For regex data, the input string is copied to newly allocated
- * memory and also compiled to a regex. Use sdb_data_free_datum() to free the
- * dynamically allocated memory.
- *
- * The input string may be stored in 'data', that is, the function may be used
- * to do an inline cast from a string to any other type. It is the callers
- * responsibility to free the memory used by the string in case the target
- * type does not keep a reference to it.
+ * specified as (floating point) number of seconds since the epoch. New memory
+ * will be allocated as necessary and will have to be free'd using
+ * sdb_data_free_datum().
  *
  * Returns:
  *  - 0 on success
  *  - a negative value else
  */
 int
-sdb_data_parse(char *str, int type, sdb_data_t *data);
+sdb_data_parse(const char *str, int type, sdb_data_t *data);
 
 /*
  * sdb_data_sizeof:
index 6f4d5cc2e090350be92920ed3d074a18adaf091a..653664145910084cd7adc2e7b59de3ad2d597e56 100644 (file)
@@ -134,6 +134,9 @@ sdb_unixsock_client_process_one_line(sdb_unixsock_client_t *client,
 
        if (callback(client, (size_t)column_count, data, user_data))
                return -1;
+
+       for (i = 0; i < column_count; ++i)
+               sdb_data_free_datum(&data[i]);
        return 0;
 } /* sdb_unixsock_client_process_one_line */
 
index 2b32d8b91a169290d0b6a3a2806d99fe72ad2de4..cf2603575bc0fa3a3ff47f5de1f2225e2d167e53 100644 (file)
@@ -2168,19 +2168,18 @@ START_TEST(test_parse)
                                golden_data[i].input, type);
 
                if (type == SDB_TYPE_STRING)
-                       fail_unless(golden_data[i].input == result.data.string,
-                                       "sdb_data_parse(%s, %d, <d>) modified input string",
+                       fail_unless(golden_data[i].input != result.data.string,
+                                       "sdb_data_parse(%s, %d, <d>) copied input string",
                                        golden_data[i].input, type);
                if (type == SDB_TYPE_BINARY)
-                       fail_unless(golden_data[i].input == (char *)result.data.binary.datum,
-                                       "sdb_data_parse(%s, %d, <d>) modified input string",
+                       fail_unless(golden_data[i].input != (char *)result.data.binary.datum,
+                                       "sdb_data_parse(%s, %d, <d>) copied input string",
                                        golden_data[i].input, type);
-               if (type == SDB_TYPE_REGEX) {
+               if (type == SDB_TYPE_REGEX)
                        fail_unless(golden_data[i].input != result.data.re.raw,
                                        "sdb_data_parse(%s, %d, <d>) copied input string",
                                        golden_data[i].input, type);
-                       sdb_data_free_datum(&result);
-               }
+               sdb_data_free_datum(&result);
        }
 }
 END_TEST