summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--action.c2
-rw-r--r--template.c90
-rw-r--r--template.h9
3 files changed, 63 insertions, 38 deletions
diff --git a/action.c b/action.c
index 278625ce..6796cf14 100644
--- a/action.c
+++ b/action.c
@@ -1743,7 +1743,7 @@ addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringReques
}
/* check required template options */
if( (iTplOpts & OMSR_RQD_TPL_OPT_SQL)
- && (pAction->ppTpl[i]->optFormatForSQL == 0)) {
+ && (pAction->ppTpl[i]->optFormatEscape == 0)) {
errno = 0;
errmsg.LogError(0, RS_RET_RQD_TPLOPT_MISSING, "Action disabled. To use this action, you have to specify "
"the SQL or stdSQL option in your template!\n");
diff --git a/template.c b/template.c
index 2038c6c1..54ca95af 100644
--- a/template.c
+++ b/template.c
@@ -53,7 +53,12 @@ static struct template *tplRoot = NULL; /* the root of the template list */
static struct template *tplLast = NULL; /* points to the last element of the template list */
static struct template *tplLastStatic = NULL; /* last static element of the template list */
-
+enum {
+ NO_ESCAPE = 0,
+ SQL_ESCAPE,
+ STDSQL_ESCAPE,
+ JSON_ESCAPE,
+};
/* helper to tplToString and strgen's, extends buffer */
#define ALLOC_INC 128
@@ -123,10 +128,12 @@ rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *
* but they are handled in this way because of legacy (don't break any
* existing thing).
*/
- if(pTpl->optFormatForSQL == 1)
- doSQLEscape(&pVal, &iLenVal, &bMustBeFreed, 1);
- else if(pTpl->optFormatForSQL == 2)
- doSQLEscape(&pVal, &iLenVal, &bMustBeFreed, 0);
+ if(pTpl->optFormatEscape == SQL_ESCAPE)
+ doEscape(&pVal, &iLenVal, &bMustBeFreed, SQL_ESCAPE);
+ else if(pTpl->optFormatEscape == JSON_ESCAPE)
+ doEscape(&pVal, &iLenVal, &bMustBeFreed, JSON_ESCAPE);
+ else if(pTpl->optFormatEscape == STDSQL_ESCAPE)
+ doEscape(&pVal, &iLenVal, &bMustBeFreed, STDSQL_ESCAPE);
}
/* got source, now copy over */
if(iLenVal > 0) { /* may be zero depending on property */
@@ -213,27 +220,29 @@ finalize_it:
}
-/* Helper to doSQLEscape. This is called if doSQLEscape
+/* Helper to doEscape. This is called if doEscape
* runs out of memory allocating the escaped string.
* Then we are in trouble. We can
* NOT simply return the unmodified string because this
* may cause SQL injection. But we also can not simply
* abort the run, this would be a DoS. I think an appropriate
- * measure is to remove the dangerous \' characters. We
+ * measure is to remove the dangerous \' characters (SQL). We
* replace them by \", which will break the message and
* signatures eventually present - but this is the
* best thing we can do now (or does anybody
* have a better idea?). rgerhards 2004-11-23
- * added support for "escapeMode" (so doSQLEscape for details).
- * if mode = 1, then backslashes are changed to slashes.
+ * added support for escape mode (see doEscape for details).
+ * if mode = SQL_ESCAPE, then backslashes are changed to slashes.
* rgerhards 2005-09-22
*/
-static void doSQLEmergencyEscape(register uchar *p, int escapeMode)
+static void doEmergencyEscape(register uchar *p, int mode)
{
while(*p) {
- if(*p == '\'')
+ if((mode == SQL_ESCAPE||mode == STDSQL_ESCAPE) && *p == '\'')
*p = '"';
- else if((escapeMode == 1) && (*p == '\\'))
+ else if((mode == JSON_ESCAPE) && *p == '"')
+ *p = '\'';
+ else if((mode == SQL_ESCAPE) && *p == '\\')
*p = '/';
++p;
}
@@ -258,14 +267,16 @@ static void doSQLEmergencyEscape(register uchar *p, int escapeMode)
* smartness depends on config settings. So we add a new option to this
* function that allows the caller to select if they want to standard or
* "smart" encoding ;)
- * new parameter escapeMode is 0 - standard sql, 1 - "smart" engines
+ * --
+ * Parameter "mode" is STDSQL_ESCAPE, SQL_ESCAPE "smart" SQL engines, or
+ * JSON_ESCAPE for everyone requiring escaped JSON (e.g. ElasticSearch).
* 2005-09-22 rgerhards
*/
rsRetVal
-doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode)
+doEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int mode)
{
DEFiRet;
- uchar *p;
+ uchar *p = NULL;
int iLen;
cstr_t *pStrB = NULL;
uchar *pszGenerated;
@@ -276,26 +287,32 @@ doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeM
assert(pbMustBeFreed != NULL);
/* first check if we need to do anything at all... */
- if(escapeMode == 0)
+ if(mode == STDSQL_ESCAPE)
for(p = *pp ; *p && *p != '\'' ; ++p)
;
- else
+ else if(mode == SQL_ESCAPE)
for(p = *pp ; *p && *p != '\'' && *p != '\\' ; ++p)
;
+ else if(mode == JSON_ESCAPE)
+ for(p = *pp ; *p && *p != '"' ; ++p)
+ ;
/* when we get out of the loop, we are either at the
- * string terminator or the first \'. */
- if(*p == '\0')
+ * string terminator or the first character to escape */
+ if(p && *p == '\0')
FINALIZE; /* nothing to do in this case! */
p = *pp;
iLen = *pLen;
CHKiRet(cstrConstruct(&pStrB));
-
+
while(*p) {
- if(*p == '\'') {
- CHKiRet(cstrAppendChar(pStrB, (escapeMode == 0) ? '\'' : '\\'));
+ if((mode == SQL_ESCAPE || mode == STDSQL_ESCAPE) && *p == '\'') {
+ CHKiRet(cstrAppendChar(pStrB, (mode == STDSQL_ESCAPE) ? '\'' : '\\'));
+ iLen++; /* reflect the extra character */
+ } else if((mode == SQL_ESCAPE) && *p == '\\') {
+ CHKiRet(cstrAppendChar(pStrB, '\\'));
iLen++; /* reflect the extra character */
- } else if((escapeMode == 1) && (*p == '\\')) {
+ } else if((mode == JSON_ESCAPE) && *p == '"') {
CHKiRet(cstrAppendChar(pStrB, '\\'));
iLen++; /* reflect the extra character */
}
@@ -314,7 +331,7 @@ doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeM
finalize_it:
if(iRet != RS_RET_OK) {
- doSQLEmergencyEscape(*pp, escapeMode);
+ doEmergencyEscape(*pp, mode);
if(pStrB != NULL)
cstrDestruct(&pStrB);
}
@@ -883,11 +900,14 @@ tplAddTplMod(struct template *pTpl, uchar** ppRestOfConfLine)
* acknowledged implementing the option. -- rgerhards, 2011-03-21
*/
if(lenMod > 6 && !strcasecmp((char*) szMod + lenMod - 7, ",stdsql")) {
- pTpl->optFormatForSQL = 2;
- DBGPRINTF("strgen suports the stdsql option\n");
+ pTpl->optFormatEscape = STDSQL_ESCAPE;
+ DBGPRINTF("strgen supports the stdsql option\n");
} else if(lenMod > 3 && !strcasecmp((char*) szMod+ lenMod - 4, ",sql")) {
- pTpl->optFormatForSQL = 1;
- DBGPRINTF("strgen suports the sql option\n");
+ pTpl->optFormatEscape = SQL_ESCAPE;
+ DBGPRINTF("strgen supports the sql option\n");
+ } else if(lenMod > 4 && !strcasecmp((char*) szMod+ lenMod - 4, ",json")) {
+ pTpl->optFormatEscape = JSON_ESCAPE;
+ DBGPRINTF("strgen supports the json option\n");
}
finalize_it:
@@ -1015,11 +1035,13 @@ struct template *tplAddLine(char* pName, uchar** ppRestOfConfLine)
* it anyhow... ;) rgerhards 2004-11-22
*/
if(!strcmp(optBuf, "stdsql")) {
- pTpl->optFormatForSQL = 2;
+ pTpl->optFormatEscape = STDSQL_ESCAPE;
+ } else if(!strcmp(optBuf, "json")) {
+ pTpl->optFormatEscape = JSON_ESCAPE;
} else if(!strcmp(optBuf, "sql")) {
- pTpl->optFormatForSQL = 1;
+ pTpl->optFormatEscape = SQL_ESCAPE;
} else if(!strcmp(optBuf, "nosql")) {
- pTpl->optFormatForSQL = 0;
+ pTpl->optFormatEscape = NO_ESCAPE;
} else {
dbgprintf("Invalid option '%s' ignored.\n", optBuf);
}
@@ -1180,9 +1202,11 @@ void tplPrintList(void)
pTpl = tplRoot;
while(pTpl != NULL) {
dbgprintf("Template: Name='%s' ", pTpl->pszName == NULL? "NULL" : pTpl->pszName);
- if(pTpl->optFormatForSQL == 1)
+ if(pTpl->optFormatEscape == SQL_ESCAPE)
dbgprintf("[SQL-Format (MySQL)] ");
- else if(pTpl->optFormatForSQL == 2)
+ else if(pTpl->optFormatEscape == JSON_ESCAPE)
+ dbgprintf("[JSON-Escaped Format] ");
+ else if(pTpl->optFormatEscape == STDSQL_ESCAPE)
dbgprintf("[SQL-Format (standard SQL)] ");
dbgprintf("\n");
pTpe = pTpl->pEntryRoot;
diff --git a/template.h b/template.h
index f7ac2e08..b5598b6d 100644
--- a/template.h
+++ b/template.h
@@ -36,9 +36,10 @@ struct template {
int tpenElements; /* number of elements in templateEntry list */
struct templateEntry *pEntryRoot;
struct templateEntry *pEntryLast;
- char optFormatForSQL; /* in text fields, 0 - do not escape,
- * 1 - escape quotes by double quotes,
- * 2 - escape "the MySQL way"
+ char optFormatEscape; /* in text fields, 0 - do not escape,
+ * 1 - escape "the MySQL way"
+ * 2 - escape quotes by double quotes,
+ * 3 - escape double quotes for JSON.
*/
/* following are options. All are 0/1 defined (either on or off).
* we use chars because they are faster than bit fields and smaller
@@ -130,7 +131,7 @@ rsRetVal ExtendBuf(uchar **pBuf, size_t *pLenBuf, size_t iMinSize);
*/
rsRetVal tplToArray(struct template *pTpl, msg_t *pMsg, uchar*** ppArr);
rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar** ppSz, size_t *);
-rsRetVal doSQLEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode);
+rsRetVal doEscape(uchar **pp, size_t *pLen, unsigned short *pbMustBeFreed, int escapeMode);
rsRetVal templateInit();