mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-29 00:23:23 -05:00
[daap] Unescaping of \' in the value part of a daap clause
This commit is contained in:
parent
6238647202
commit
9233c03ca8
@ -36,11 +36,15 @@ daap_query_parse_sql(const char *daap_query)
|
|||||||
{
|
{
|
||||||
struct daap_result result;
|
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)
|
if (daap_lex_parse(&result, daap_query) != 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_DAAP, "Could not parse '%s': %s\n", daap_query, result.errmsg);
|
DPRINTF(E_LOG, L_DAAP, "Could not parse '%s': %s\n", daap_query, result.errmsg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_SPAM, L_DAAP, "Parse DAAP query output '%s'\n", result.str);
|
||||||
|
|
||||||
return safe_strdup(result.str);
|
return safe_strdup(result.str);
|
||||||
}
|
}
|
||||||
|
@ -182,32 +182,9 @@ int daap_lex_parse(struct daap_result *result, const char *input);
|
|||||||
#ifndef DEBUG_PARSER_MOCK
|
#ifndef DEBUG_PARSER_MOCK
|
||||||
#include "daap_query_hash.h"
|
#include "daap_query_hash.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "misc.h"
|
||||||
#else
|
#else
|
||||||
struct dmap_query_field_map {
|
#include "owntonefunctions.h"
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,48 +199,6 @@ struct daap_result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
%code {
|
%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, ...)
|
static void sql_append(struct daap_result *result, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -317,6 +252,8 @@ static void sql_like_escape(char **value, char *escape_char)
|
|||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
char *new;
|
char *new;
|
||||||
|
|
||||||
|
*escape_char = 0;
|
||||||
|
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
return; // Shouldn't ever happen since lexer should give strings w/wildcards
|
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
|
len = 2 * len; // Enough for every char to be escaped
|
||||||
new = realloc(s, len);
|
new = realloc(s, len);
|
||||||
str_replace(new, len, "%", "\\%");
|
safe_snreplace(new, len, "%", "\\%");
|
||||||
str_replace(new, len, "_", "\\_");
|
safe_snreplace(new, len, "_", "\\_");
|
||||||
new[0] = new[strlen(new) - 1] = '%';
|
new[0] = new[strlen(new) - 1] = '%';
|
||||||
*escape_char = '\\';
|
*escape_char = '\\';
|
||||||
*value = new;
|
*value = new;
|
||||||
@ -338,9 +275,13 @@ static void sql_like_escape(char **value, char *escape_char)
|
|||||||
|
|
||||||
static void sql_str_escape(char **value)
|
static void sql_str_escape(char **value)
|
||||||
{
|
{
|
||||||
char *old = *value;
|
char *s = *value;
|
||||||
*value = db_escape_string(old);
|
|
||||||
free(old);
|
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)
|
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 */
|
/* 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)
|
if (!a || result->err < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user