aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/third_party/include/libinjection_sqli.h22
-rw-r--r--src/lib/third_party/src/libinjection_html5.c20
-rw-r--r--src/lib/third_party/src/libinjection_sqli.c37
-rw-r--r--src/lib/third_party/src/libinjection_xss.c23
4 files changed, 69 insertions, 33 deletions
diff --git a/src/lib/third_party/include/libinjection_sqli.h b/src/lib/third_party/include/libinjection_sqli.h
index b9746555a..a6c96ff51 100644
--- a/src/lib/third_party/include/libinjection_sqli.h
+++ b/src/lib/third_party/include/libinjection_sqli.h
@@ -175,7 +175,7 @@ struct libinjection_sqli_state {
typedef struct libinjection_sqli_state sfilter;
struct libinjection_sqli_token* libinjection_sqli_get_token(
- struct libinjection_sqli_state* sqlistate, int i);
+ struct libinjection_sqli_state* sql_state, int i);
/*
* Version info.
@@ -193,8 +193,8 @@ const char* libinjection_version(void);
/**
*
*/
-void libinjection_sqli_init(struct libinjection_sqli_state* sql_state,
- const char* s, size_t slen,
+void libinjection_sqli_init(struct libinjection_sqli_state *sf,
+ const char* s, size_t len,
int flags);
/**
@@ -210,7 +210,7 @@ int libinjection_is_sqli(struct libinjection_sqli_state* sql_state);
/* FOR HACKERS ONLY
* provides deep hooks into the decision making process
*/
-void libinjection_sqli_callback(struct libinjection_sqli_state* sql_state,
+void libinjection_sqli_callback(struct libinjection_sqli_state *sf,
ptr_lookup_fn fn,
void* userdata);
@@ -218,7 +218,7 @@ void libinjection_sqli_callback(struct libinjection_sqli_state* sql_state,
/*
* Resets state, but keeps initial string and callbacks
*/
-void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state,
+void libinjection_sqli_reset(struct libinjection_sqli_state *sf,
int flags);
/**
@@ -236,17 +236,17 @@ void libinjection_sqli_reset(struct libinjection_sqli_state* sql_state,
* do not free!
*
*/
-const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state* sql_state,
+const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state *sql_state,
int flags);
/**
* The default "word" to token-type or fingerprint function. This
* uses a ASCII case-insensitive binary tree.
*/
-char libinjection_sqli_lookup_word(struct libinjection_sqli_state* sql_state,
+char libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state,
int lookup_type,
- const char* s,
- size_t slen);
+ const char* str,
+ size_t len);
/* Streaming tokenization interface.
*
@@ -255,13 +255,13 @@ char libinjection_sqli_lookup_word(struct libinjection_sqli_state* sql_state,
* \returns 1, has a token, keep going, or 0 no tokens
*
*/
-int libinjection_sqli_tokenize(struct libinjection_sqli_state * sql_state);
+int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf);
/**
* parses and folds input, up to 5 tokens
*
*/
-int libinjection_sqli_fold(struct libinjection_sqli_state * sql_state);
+int libinjection_sqli_fold(struct libinjection_sqli_state *sf);
/** The built-in default function to match fingerprints
* and do false negative/positive analysis. This calls the following
diff --git a/src/lib/third_party/src/libinjection_html5.c b/src/lib/third_party/src/libinjection_html5.c
index a380ca0ad..640f62656 100644
--- a/src/lib/third_party/src/libinjection_html5.c
+++ b/src/lib/third_party/src/libinjection_html5.c
@@ -29,7 +29,7 @@
/* prototypes */
static int h5_skip_white(h5_state_t* hs);
-static int h5_is_white(char c);
+static int h5_is_white(char ch);
static int h5_state_eof(h5_state_t* hs);
static int h5_state_data(h5_state_t* hs);
static int h5_state_tag_open(h5_state_t* hs);
@@ -323,6 +323,10 @@ static int h5_state_before_attribute_name(h5_state_t* hs)
int ch;
TRACE();
+
+ /* for manual tail call optimization, see comment below */
+ tail_call:;
+
ch = h5_skip_white(hs);
switch (ch) {
case CHAR_EOF: {
@@ -330,6 +334,18 @@ static int h5_state_before_attribute_name(h5_state_t* hs)
}
case CHAR_SLASH: {
hs->pos += 1;
+ /* Logically, We want to call h5_state_self_closing_start_tag(hs) here.
+
+ As this function may call us back and the compiler
+ might not implement automatic tail call optimization,
+ this might result in a deep recursion.
+
+ We detect this case here and start over with the current state.
+ */
+
+ if (hs->pos < hs->len && hs->s[hs->pos] != CHAR_GT) {
+ goto tail_call;
+ }
return h5_state_self_closing_start_tag(hs);
}
case CHAR_GT: {
@@ -574,6 +590,8 @@ static int h5_state_after_attribute_value_quoted_state(h5_state_t* hs)
/**
* 12.2.4.43
+ *
+ * WARNING: This function is partially inlined into h5_state_before_attribute_name()
*/
static int h5_state_self_closing_start_tag(h5_state_t* hs)
{
diff --git a/src/lib/third_party/src/libinjection_sqli.c b/src/lib/third_party/src/libinjection_sqli.c
index c41167734..058d08deb 100644
--- a/src/lib/third_party/src/libinjection_sqli.c
+++ b/src/lib/third_party/src/libinjection_sqli.c
@@ -18,7 +18,7 @@
#include "libinjection_sqli.h"
#include "libinjection_sqli_data.h"
-#define LIBINJECTION_VERSION "3.9.2"
+#define LIBINJECTION_VERSION "3.9.2.60-8e70-dirty"
#define LIBINJECTION_SQLI_TOKEN_SIZE sizeof(((stoken_t*)(0))->val)
#define LIBINJECTION_SQLI_MAX_TOKENS 5
@@ -503,12 +503,7 @@ static size_t parse_slash(struct libinjection_sqli_state * sf)
* skip over initial '/x'
*/
ptr = memchr2(cur + 2, slen - (pos + 2), '*', '/');
-
- /*
- * (ptr == NULL) causes false positive in cppcheck 1.61
- * casting to type seems to fix it
- */
- if (ptr == (const char*) NULL) {
+ if (ptr == NULL) {
/* till end of line */
clen = slen - pos;
} else {
@@ -525,7 +520,10 @@ static size_t parse_slash(struct libinjection_sqli_state * sf)
* are an automatic black ban!
*/
- if(ptr && (memchr2(cur + 2, (size_t)(ptr - (cur + 1)), '/', '*') != NULL)) {
+ if (
+ ptr != NULL &&
+ memchr2(cur + 2, (size_t)(ptr - (cur + 1)), '/', '*') != NULL
+ ) {
ctype = TYPE_EVIL;
} else if (is_mysql_comment(cs, slen, pos)) {
ctype = TYPE_EVIL;
@@ -599,6 +597,16 @@ static size_t parse_operator2(struct libinjection_sqli_state * sf)
}
}
+#ifndef __clang_analyzer__
+/* Code not to be analyzed by clang.
+ *
+ * Why we do this? Because there is a false positive here:
+ * libinjection_sqli.c:608:13: warning: Out of bound memory access (access exceeds upper limit of memory block) [alpha.security.ArrayBoundV2]
+ * if (*ptr != '\\') {
+ * ^~~~
+ * Specifically, this function deals with non-null terminated char arrays. This can be added
+ * as prerequisite, and is not written clearly. But the math in the for below holds.
+ */
/*
* Ok! " \" " one backslash = escaped!
* " \\" " two backslash = not escaped!
@@ -616,6 +624,7 @@ static int is_backslash_escaped(const char* end, const char* start)
return (end - ptr) & 1;
}
+#endif
static size_t is_double_delim_escaped(const char* cur, const char* end)
{
@@ -1066,9 +1075,9 @@ static size_t parse_money(struct libinjection_sqli_state *sf)
}
/* we have $foobar$ ... find it again */
- strend = my_memmem(cs+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2);
+ strend = my_memmem(cs+pos+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2);
- if (strend == NULL || ((size_t)(strend - cs) < (pos+xlen+2))) {
+ if (strend == NULL) {
/* fell off edge */
st_assign(sf->current, TYPE_STRING, pos+xlen+2, slen - pos - xlen - 2, cs+pos+xlen+2);
sf->current->str_open = '$';
@@ -1197,12 +1206,12 @@ static size_t parse_number(struct libinjection_sqli_state * sf)
* without having to regenerated the SWIG (or other binding) in minor
* releases.
*/
-const char* libinjection_version()
+const char* libinjection_version(void)
{
return LIBINJECTION_VERSION;
}
-int libinjection_sqli_tokenize(struct libinjection_sqli_state * sf)
+int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf)
{
pt2Function fnptr;
size_t *pos = &sf->pos;
@@ -2309,12 +2318,12 @@ int libinjection_is_sqli(struct libinjection_sqli_state * sql_state)
return FALSE;
}
-int libinjection_sqli(const char* input, size_t slen, char fingerprint[])
+int libinjection_sqli(const char* s, size_t slen, char fingerprint[])
{
int issqli;
struct libinjection_sqli_state state;
- libinjection_sqli_init(&state, input, slen, 0);
+ libinjection_sqli_init(&state, s, slen, 0);
issqli = libinjection_is_sqli(&state);
if (issqli) {
strcpy(fingerprint, state.fingerprint);
diff --git a/src/lib/third_party/src/libinjection_xss.c b/src/lib/third_party/src/libinjection_xss.c
index f0df4d84a..3ef827df9 100644
--- a/src/lib/third_party/src/libinjection_xss.c
+++ b/src/lib/third_party/src/libinjection_xss.c
@@ -20,7 +20,7 @@ static int is_black_tag(const char* s, size_t len);
static int is_black_url(const char* s, size_t len);
static int cstrcasecmp_with_null(const char *a, const char *b, size_t n);
static int html_decode_char_at(const char* src, size_t len, size_t* consumed);
-static int htmlencode_startswith(const char* prefix, const char *src, size_t n);
+static int htmlencode_startswith(const char *a/* prefix */, const char *b /* src */, size_t n);
typedef struct stringtype {
@@ -509,22 +509,31 @@ int libinjection_is_xss(const char* s, size_t len, int flags)
/*
* wrapper
+ *
+ *
+ * const char* s: is expected to be a null terminated string.
+ * size_t len: should represent the length of the string
+ * without the null terminator - strlen(s).
+ *
+ * Further info:
+ * - https://github.com/client9/libinjection/issues/150
+ *
*/
-int libinjection_xss(const char* s, size_t len)
+int libinjection_xss(const char* s, size_t slen)
{
- if (libinjection_is_xss(s, len, DATA_STATE)) {
+ if (libinjection_is_xss(s, slen, DATA_STATE)) {
return 1;
}
- if (libinjection_is_xss(s, len, VALUE_NO_QUOTE)) {
+ if (libinjection_is_xss(s, slen, VALUE_NO_QUOTE)) {
return 1;
}
- if (libinjection_is_xss(s, len, VALUE_SINGLE_QUOTE)) {
+ if (libinjection_is_xss(s, slen, VALUE_SINGLE_QUOTE)) {
return 1;
}
- if (libinjection_is_xss(s, len, VALUE_DOUBLE_QUOTE)) {
+ if (libinjection_is_xss(s, slen, VALUE_DOUBLE_QUOTE)) {
return 1;
}
- if (libinjection_is_xss(s, len, VALUE_BACK_QUOTE)) {
+ if (libinjection_is_xss(s, slen, VALUE_BACK_QUOTE)) {
return 1;
}