more utf-8 err checking prevents bogus terms in index

This commit is contained in:
Jean-Francois Dockes
2013-03-30 10:24:10 +01:00
parent 2018ef76b8
commit 0ae8ec99f6
6 changed files with 54 additions and 23 deletions
+1 -1
View File
@@ -462,7 +462,7 @@ string url_encode(const string& url, string::size_type offs)
string out = url.substr(0, offs);
const char *cp = url.c_str();
for (string::size_type i = offs; i < url.size(); i++) {
int c;
unsigned int c;
const char *h = "0123456789ABCDEF";
c = cp[i];
if (c <= 0x20 ||
+4 -2
View File
@@ -28,6 +28,7 @@ using std::string;
#include "cstr.h"
#include "debuglog.h"
#include "strmatcher.h"
#include "pathut.h"
bool StrWildMatcher::match(const string& val) const
{
@@ -38,8 +39,9 @@ bool StrWildMatcher::match(const string& val) const
case 0: return true;
case FNM_NOMATCH: return false;
default:
LOGDEB0(("StrWildMatcher::match error: [%s] against [%s]\n",
m_sexp.c_str(), val.c_str()));
LOGINFO(("StrWildMatcher::match:err: e [%s] s [%s] (%s) ret %d\n",
m_sexp.c_str(), val.c_str(),
url_encode(val).c_str(), ret));
return false;
}
}
+41 -18
View File
@@ -32,7 +32,7 @@
class Utf8Iter {
public:
Utf8Iter(const std::string &in)
: m_s(in), m_cl(0), m_pos(0), m_charpos(0), m_error(false)
: m_s(in), m_cl(0), m_pos(0), m_charpos(0)
{
update_cl();
}
@@ -44,7 +44,6 @@ public:
m_cl = 0;
m_pos = 0;
m_charpos = 0;
m_error = false;
update_cl();
}
@@ -62,15 +61,15 @@ public:
int l;
while (mypos < m_s.length() && mycp != charpos) {
l = get_cl(mypos);
if (l <= 0)
if (l <= 0 || !poslok(mypos, l) || !checkvalidat(mypos, l))
return (unsigned int)-1;
mypos += l;
++mycp;
}
if (mypos < m_s.length() && mycp == charpos) {
l = get_cl(mypos);
if (poslok(mypos, l))
return getvalueat(mypos, get_cl(mypos));
if (poslok(mypos, l) && checkvalidat(mypos, l))
return getvalueat(mypos, l);
}
return (unsigned int)-1;
}
@@ -83,7 +82,7 @@ public:
#ifdef UTF8ITER_CHECK
assert(m_cl != 0);
#endif
if (m_cl <= 0)
if (m_cl == 0)
return std::string::npos;
m_pos += m_cl;
@@ -96,9 +95,9 @@ public:
unsigned int operator*()
{
#ifdef UTF8ITER_CHECK
assert(m_cl != 0);
assert(m_cl > 0);
#endif
return getvalueat(m_pos, m_cl);
return m_cl == 0 ? (unsigned int)-1 : getvalueat(m_pos, m_cl);
}
/** Append current utf-8 possibly multi-byte character to string param.
@@ -116,15 +115,15 @@ public:
#ifdef UTF8ITER_CHECK
assert(m_cl != 0);
#endif
return m_s.substr(m_pos, m_cl);
return m_cl > 0 ? m_s.substr(m_pos, m_cl) : std::string();
}
bool eof() {
bool eof() const {
return m_pos == m_s.length();
}
bool error() {
return m_error;
bool error() const {
return m_cl == 0;
}
/** Return current byte offset in input string */
@@ -147,13 +146,11 @@ private:
const std::string& m_s;
// Character length at current position. A value of zero indicates
// an error.
unsigned int m_cl;
unsigned int m_cl;
// Current byte offset in string.
std::string::size_type m_pos;
// Current character position
unsigned int m_charpos;
// Am I ok ?
mutable bool m_error;
// Check position and cl against string length
bool poslok(std::string::size_type p, int l) const {
@@ -163,7 +160,7 @@ private:
return p != std::string::npos && l > 0 && p + l <= m_s.length();
}
// Update current char length in object state, minimum checking
// Update current char length in object state, check
// for errors
inline void update_cl()
{
@@ -176,7 +173,34 @@ private:
// basically prevents the caller to discriminate error and eof.
// m_pos = m_s.length();
m_cl = 0;
m_error = true;
return;
}
if (!checkvalidat(m_pos, m_cl)) {
m_cl = 0;
}
}
inline bool checkvalidat(std::string::size_type p, int l) const
{
switch (l) {
case 1:
return (unsigned char)m_s[p] < 128;
case 2:
return (((unsigned char)m_s[p]) & 224) == 192
&& (((unsigned char)m_s[p+1]) & 192) == 128;
case 3:
return (((unsigned char)m_s[p]) & 240) == 224
&& (((unsigned char)m_s[p+1]) & 192) == 128
&& (((unsigned char)m_s[p+2]) & 192) == 128
;
case 4:
return (((unsigned char)m_s[p]) & 248) == 240
&& (((unsigned char)m_s[p+1]) & 192) == 128
&& (((unsigned char)m_s[p+2]) & 192) == 128
&& (((unsigned char)m_s[p+3]) & 192) == 128
;
default:
return false;
}
}
@@ -249,7 +273,6 @@ private:
#ifdef UTF8ITER_CHECK
assert(l <= 4);
#endif
m_error = true;
return (unsigned int)-1;
}
}