p = chunk->pos;
- /* Skip any spaces */
- while (p < chunk->end && g_ascii_isspace (*p)) {
- rspamd_cl_chunk_skipc (chunk, *p);
- p ++;
- }
-
while (p < chunk->end) {
/*
* A key must start with alpha and end with space character
else {
/* Invalid identifier */
rspamd_cl_set_err (chunk, RSPAMD_CL_ESYNTAX, "key must begin with a letter", err);
+ assert (0);
return FALSE;
}
}
*/
static gboolean
rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser,
- struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro, GError **err)
+ struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro,
+ guchar const **macro_start, gsize *macro_len, GError **err)
{
const guchar *p, *c;
return FALSE;
}
- if (!macro->handler (c + 1, chunk->pos - c - 2, macro->ud, err)) {
- return FALSE;
- }
+ *macro_start = c + 1;
+ *macro_len = chunk->pos - c - 2;
p = chunk->pos;
break;
case '{':
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
- if (!macro->handler (c, p - c, macro->ud, err)) {
- return FALSE;
- }
+ *macro_start = c;
+ *macro_len = p - c;
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
break;
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
- if (!macro->handler (c, p - c, macro->ud, err)) {
- return FALSE;
- }
+ *macro_start = c;
+ *macro_len = p - c;
break;
}
rspamd_cl_object_t *obj;
struct rspamd_cl_chunk *chunk = parser->chunks;
struct rspamd_cl_stack *st;
- const guchar *p, *c;
+ const guchar *p, *c, *macro_start = NULL;
+ gsize macro_len = 0;
struct rspamd_cl_macro *macro = NULL;
p = chunk->pos;
while (chunk->pos < chunk->end) {
- parser->prev_state = parser->state;
switch (parser->state) {
case RSPAMD_RCL_STATE_INIT:
/*
}
break;
case RSPAMD_RCL_STATE_KEY:
+ /* Skip any spaces */
+ while (p < chunk->end && g_ascii_isspace (*p)) {
+ rspamd_cl_chunk_skipc (chunk, *p);
+ p ++;
+ }
if (*p == '}') {
/* We have the end of an object */
parser->state = RSPAMD_RCL_STATE_AFTER_VALUE;
return FALSE;
}
/* State is set in rspamd_cl_parse_value call */
+ p = chunk->pos;
break;
case RSPAMD_RCL_STATE_AFTER_VALUE:
if (!rspamd_cl_parse_after_value (parser, chunk, err)) {
/* Skip everything at the end */
return TRUE;
}
+ p = chunk->pos;
break;
case RSPAMD_RCL_STATE_MACRO_NAME:
if (!g_ascii_isspace (*p)) {
}
break;
case RSPAMD_RCL_STATE_MACRO:
- if (!rspamd_cl_parse_macro_value (parser, chunk, macro, err)) {
+ if (!rspamd_cl_parse_macro_value (parser, chunk, macro,
+ ¯o_start, ¯o_len, err)) {
parser->prev_state = parser->state;
parser->state = RSPAMD_RCL_STATE_ERROR;
return FALSE;
}
parser->state = parser->prev_state;
+ if (!macro->handler (macro_start, macro_len, macro->ud, err)) {
+ return FALSE;
+ }
+ p = chunk->pos;
break;
default:
/* TODO: add all states */
struct rspamd_cl_chunk *chunk;
guchar *buf = NULL, *sigbuf = NULL;
gsize buflen, siglen;
- gchar filebuf[PATH_MAX];
+ gchar filebuf[PATH_MAX], realbuf[PATH_MAX];
rspamd_snprintf (filebuf, sizeof (filebuf), "%*s", len, data);
+ if (realpath (filebuf, realbuf) == NULL) {
+ g_set_error (err, RCL_ERROR, RSPAMD_CL_EIO, "cannot open file %s: %s",
+ filebuf,
+ strerror (errno));
+ return FALSE;
+ }
- if (!rspamd_cl_fetch_file (filebuf, &buf, &buflen, err)) {
+ if (!rspamd_cl_fetch_file (realbuf, &buf, &buflen, err)) {
return FALSE;
}
if (check_signature) {
#ifdef HAVE_OPENSSL
/* We need to check signature first */
- rspamd_snprintf (filebuf, sizeof (filebuf), "%*s.sig", len, data);
+ rspamd_snprintf (filebuf, sizeof (filebuf), "%s.sig", realbuf);
if (!rspamd_cl_fetch_file (filebuf, &sigbuf, &siglen, err)) {
return FALSE;
}
{
struct rspamd_cl_parser *parser = ud;
- if (*data == '/') {
+ if (*data == '/' || *data == '.') {
/* Try to load a file */
return rspamd_cl_include_file (data, len, parser, FALSE, err);
}
{
struct rspamd_cl_parser *parser = ud;
- if (*data == '/') {
+ if (*data == '/' || *data == '.') {
/* Try to load a file */
return rspamd_cl_include_file (data, len, parser, TRUE, err);
}