[misc] New utility functions: trim, atrim and safe_snprintf_cat

This commit is contained in:
ejurgensen 2018-10-06 23:27:54 +02:00
parent d3121f4ec7
commit fc5a66f86d
4 changed files with 91 additions and 50 deletions

View File

@ -6767,31 +6767,24 @@ db_statements_prepare(void)
char *query; char *query;
char keystr[2048]; char keystr[2048];
char valstr[1024]; char valstr[1024];
int keyremain;
int valremain;
int ret; int ret;
int i; int i;
// Prepare "INSERT INTO files" statement // Prepare "INSERT INTO files" statement
keyremain = sizeof(keystr); memset(keystr, 0, sizeof(keystr));
valremain = sizeof(valstr); memset(valstr, 0, sizeof(valstr));
for (i = 0; i < ARRAY_SIZE(mfi_cols_map); i++) for (i = 0; i < ARRAY_SIZE(mfi_cols_map); i++)
{ {
if (mfi_cols_map[i].flag == DB_FLAG_AUTO) if (mfi_cols_map[i].flag == DB_FLAG_AUTO)
continue; continue;
keyremain -= snprintf(keystr + sizeof(keystr) - keyremain, keyremain, "%s, ", mfi_cols_map[i].name); CHECK_ERR(L_DB, safe_snprintf_cat(keystr, sizeof(keystr), "%s, ", mfi_cols_map[i].name));
valremain -= snprintf(valstr + sizeof(valstr) - valremain, valremain, "?, "); CHECK_ERR(L_DB, safe_snprintf_cat(valstr, sizeof(valstr), "?, "));
if (keyremain <= 0 || valremain <= 0)
{
DPRINTF(E_FATAL, L_DB, "Bug! Size of keystr or valstr is insufficient (%d, %d)\n", keyremain, valremain);
return -1;
}
} }
// Terminates at the ending ", " // Terminate at the ending ", "
keystr[sizeof(keystr) - keyremain - 2] = '\0'; *(strrchr(keystr, ',')) = '\0';
valstr[sizeof(valstr) - valremain - 2] = '\0'; *(strrchr(valstr, ',')) = '\0';
CHECK_NULL(L_DB, query = db_mprintf("INSERT INTO files (%s) VALUES (%s);", keystr, valstr)); CHECK_NULL(L_DB, query = db_mprintf("INSERT INTO files (%s) VALUES (%s);", keystr, valstr));
@ -6806,22 +6799,17 @@ db_statements_prepare(void)
free(query); free(query);
// Prepare "UPDATE files" statement // Prepare "UPDATE files" statement
keyremain = sizeof(keystr); memset(keystr, 0, sizeof(keystr));
for (i = 0; i < ARRAY_SIZE(mfi_cols_map); i++) for (i = 0; i < ARRAY_SIZE(mfi_cols_map); i++)
{ {
if (mfi_cols_map[i].flag == DB_FLAG_AUTO) if (mfi_cols_map[i].flag == DB_FLAG_AUTO)
continue; continue;
keyremain -= snprintf(keystr + sizeof(keystr) - keyremain, keyremain, "%s = ?, ", mfi_cols_map[i].name); CHECK_ERR(L_DB, safe_snprintf_cat(keystr, sizeof(keystr), "%s = ?, ", mfi_cols_map[i].name));
if (keyremain <= 0)
{
DPRINTF(E_FATAL, L_DB, "Bug! Size of keystr is insufficient (%d)\n", keyremain);
return -1;
}
} }
// Terminates at the ending ", " // Terminate at the ending ", "
keystr[sizeof(keystr) - keyremain - 2] = '\0'; *(strrchr(keystr, ',')) = '\0';
CHECK_NULL(L_DB, query = db_mprintf("UPDATE files SET %s WHERE %s = ?;", keystr, mfi_cols_map[0].name)); CHECK_NULL(L_DB, query = db_mprintf("UPDATE files SET %s WHERE %s = ?;", keystr, mfi_cols_map[0].name));

View File

@ -154,7 +154,7 @@ response_process(struct http_client_ctx *ctx, char **errmsg)
DPRINTF(E_DBG, L_LASTFM, "LastFM response:\n%s\n", body); DPRINTF(E_DBG, L_LASTFM, "LastFM response:\n%s\n", body);
if (errmsg) if (errmsg)
*errmsg = trimwhitespace(mxmlGetOpaque(e_node)); *errmsg = atrim(mxmlGetOpaque(e_node));
mxmlDelete(tree); mxmlDelete(tree);
return -1; return -1;
@ -180,7 +180,7 @@ response_process(struct http_client_ctx *ctx, char **errmsg)
return -1; return -1;
} }
sk = trimwhitespace(mxmlGetOpaque(s_node)); sk = atrim(mxmlGetOpaque(s_node));
if (sk) if (sk)
{ {
DPRINTF(E_LOG, L_LASTFM, "Got session key from LastFM: %s\n", sk); DPRINTF(E_LOG, L_LASTFM, "Got session key from LastFM: %s\n", sk);

View File

@ -33,6 +33,7 @@
#include <errno.h> #include <errno.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <limits.h> #include <limits.h>
#include <sys/param.h> #include <sys/param.h>
#ifndef CLOCK_REALTIME #ifndef CLOCK_REALTIME
@ -341,6 +342,7 @@ safe_asprintf(const char *fmt, ...)
{ {
char *ret = NULL; char *ret = NULL;
va_list va; va_list va;
va_start(va, fmt); va_start(va, fmt);
if (vasprintf(&ret, fmt, va) < 0) if (vasprintf(&ret, fmt, va) < 0)
{ {
@ -348,9 +350,34 @@ safe_asprintf(const char *fmt, ...)
abort(); abort();
} }
va_end(va); va_end(va);
return ret; return ret;
} }
int
safe_snprintf_cat(char *dst, size_t n, const char *fmt, ...)
{
size_t dstlen;
va_list va;
int ret;
if (!dst || !fmt)
return -1;
dstlen = strlen(dst);
if (n < dstlen)
return -1;
va_start(va, fmt);
ret = vsnprintf(dst + dstlen, n - dstlen, fmt, va);
va_end(va);
if (ret >= 0 && ret < n - dstlen)
return 0;
else
return -1;
}
/* Key/value functions */ /* Key/value functions */
struct keyval * struct keyval *
@ -586,7 +613,7 @@ m_readfile(const char *path, int num_lines)
goto error; goto error;
} }
lines[i] = trimwhitespace(line); lines[i] = atrim(line);
if (!lines[i] || (strlen(lines[i]) == 0)) if (!lines[i] || (strlen(lines[i]) == 0))
{ {
DPRINTF(E_LOG, L_MISC, "Line %d in '%s' is invalid\n", i+1, path); DPRINTF(E_LOG, L_MISC, "Line %d in '%s' is invalid\n", i+1, path);
@ -643,40 +670,58 @@ unicode_fixup_string(char *str, const char *fromcode)
} }
char * char *
trimwhitespace(const char *str) trim(char *str)
{ {
char *ptr; size_t start; // Position of first non-space char
char *start; size_t term; // Position of 0-terminator
char *out;
if (!str) if (!str)
return NULL; return NULL;
// Find the beginning start = 0;
while (isspace(*str)) term = strlen(str);
str++;
if (*str == 0) // All spaces? while ((start < term) && isspace(str[start]))
return strdup(""); start++;
while ((term > start) && isspace(str[term - 1]))
term--;
// Make copy, because we will need to insert a null terminator str[term] = '\0';
start = strdup(str);
if (!start) // Shift chars incl. terminator
if (start)
memmove(str, str + start, term - start + 1);
return str;
}
char *
atrim(const char *str)
{
size_t start; // Position of first non-space char
size_t term; // Position of 0-terminator
size_t size;
char *result;
if (!str)
return NULL; return NULL;
// Find the end start = 0;
ptr = start + strlen(start) - 1; term = strlen(str);
while (ptr > start && isspace(*ptr))
ptr--;
// Insert null terminator while ((start < term) && isspace(str[start]))
*(ptr+1) = 0; start++;
while ((term > start) && isspace(str[term - 1]))
term--;
out = strdup(start); size = term - start + 1;
free(start); result = malloc(size);
return out; memcpy(result, str + start, size);
result[size - 1] = '\0';
return result;
} }
void void

View File

@ -58,6 +58,10 @@ safe_strdup(const char *str);
char * char *
safe_asprintf(const char *fmt, ...); safe_asprintf(const char *fmt, ...);
int
safe_snprintf_cat(char *dst, size_t n, const char *fmt, ...);
/* Key/value functions */ /* Key/value functions */
struct keyval * struct keyval *
keyval_alloc(void); keyval_alloc(void);
@ -87,8 +91,13 @@ m_readfile(const char *path, int num_lines);
char * char *
unicode_fixup_string(char *str, const char *fromcode); unicode_fixup_string(char *str, const char *fromcode);
// Modifies str so it is trimmed. Returns pointer to str.
char * char *
trimwhitespace(const char *str); trim(char *str);
// Copies the trimmed part of str to a newly allocated string (caller must free)
char *
atrim(const char *str);
void void
swap_pointers(char **a, char **b); swap_pointers(char **a, char **b);
@ -105,8 +114,7 @@ b64_encode(const uint8_t *in, size_t len);
uint64_t uint64_t
murmur_hash64(const void *key, int len, uint32_t seed); murmur_hash64(const void *key, int len, uint32_t seed);
// Checks if the address is in a network that is configured as trusted
/* Checks if the address is in a network that is configured as trusted */
bool bool
peer_address_is_trusted(const char *addr); peer_address_is_trusted(const char *addr);