[daap] Unescaping of \' in the value part of a daap clause

This commit is contained in:
ejurgensen 2022-01-14 22:25:45 +01:00
parent 6238647202
commit 9233c03ca8
2 changed files with 19 additions and 73 deletions

View File

@ -36,11 +36,15 @@ daap_query_parse_sql(const char *daap_query)
{
struct daap_result result;
DPRINTF(E_SPAM, L_DAAP, "Parse DAAP query input '%s'\n", daap_query);
if (daap_lex_parse(&result, daap_query) != 0)
{
DPRINTF(E_LOG, L_DAAP, "Could not parse '%s': %s\n", daap_query, result.errmsg);
return NULL;
}
DPRINTF(E_SPAM, L_DAAP, "Parse DAAP query output '%s'\n", result.str);
return safe_strdup(result.str);
}

View File

@ -182,32 +182,9 @@ int daap_lex_parse(struct daap_result *result, const char *input);
#ifndef DEBUG_PARSER_MOCK
#include "daap_query_hash.h"
#include "db.h"
#include "misc.h"
#else
struct dmap_query_field_map {
char *dmap_field;
char *db_col;
int as_int;
};
static struct dmap_query_field_map testdqfm_int = { "daap.testint", "f.testint", 1 };
static struct dmap_query_field_map testdqfm_str = { "daap.teststr", "f.teststr", 0 };
static struct dmap_query_field_map * daap_query_field_lookup(char *tag, int len)
{
if (strcmp(tag, testdqfm_str.dmap_field) == 0)
return &testdqfm_str;
else
return &testdqfm_int;
}
static char * db_escape_string(const char *str)
{
char *new = strdup(str);
char *ptr;
while ((ptr = strpbrk(new, "\\'")))
*ptr = 'X';
return new;
}
#include "owntonefunctions.h"
#endif
}
@ -222,48 +199,6 @@ struct daap_result {
}
%code {
static int str_replace(char *s, size_t sz, const char *pattern, const char *replacement)
{
char *ptr;
char *src;
char *dst;
size_t num;
if (!s)
return -1;
if (!pattern || !replacement)
return 0;
size_t p_len = strlen(pattern);
size_t r_len = strlen(replacement);
size_t s_len = strlen(s) + 1; // Incl terminator
ptr = s;
while ((ptr = strstr(ptr, pattern)))
{
// We will move the part of the string after the pattern from src to dst
src = ptr + p_len;
dst = ptr + r_len;
num = s_len - (src - s); // Number of bytes w/terminator we need to move
if (dst + num > s + sz)
return -1; // Not enough room
// Shift everything after the pattern to the right, use memmove since
// there might be an overlap
memmove(dst, src, num);
// Write replacement, no null terminater
memcpy(ptr, replacement, r_len);
// Advance ptr to avoid infinite looping
ptr = dst;
}
return 0;
}
static void sql_append(struct daap_result *result, const char *fmt, ...)
{
va_list ap;
@ -317,6 +252,8 @@ static void sql_like_escape(char **value, char *escape_char)
size_t len = strlen(s);
char *new;
*escape_char = 0;
if (len < 2)
return; // Shouldn't ever happen since lexer should give strings w/wildcards
@ -329,8 +266,8 @@ static void sql_like_escape(char **value, char *escape_char)
len = 2 * len; // Enough for every char to be escaped
new = realloc(s, len);
str_replace(new, len, "%", "\\%");
str_replace(new, len, "_", "\\_");
safe_snreplace(new, len, "%", "\\%");
safe_snreplace(new, len, "_", "\\_");
new[0] = new[strlen(new) - 1] = '%';
*escape_char = '\\';
*value = new;
@ -338,9 +275,13 @@ static void sql_like_escape(char **value, char *escape_char)
static void sql_str_escape(char **value)
{
char *old = *value;
*value = db_escape_string(old);
free(old);
char *s = *value;
if (strchr(s, '\''))
safe_snreplace(s, strlen(s) + 1, "\\'", "'"); // See Kid's audiobooks test case
*value = db_escape_string(s);
free(s);
}
static void sql_append_dmap_clause(struct daap_result *result, struct ast *a)
@ -423,7 +364,8 @@ static void sql_append_dmap_clause(struct daap_result *result, struct ast *a)
}
/* Creates the parsing result from the AST */
static void sql_from_ast(struct daap_result *result, struct ast *a) {
static void sql_from_ast(struct daap_result *result, struct ast *a)
{
if (!a || result->err < 0)
return;