Add a few technically unnecessary but feel-good paranoia bounds checks in Dictionary.get().

This commit is contained in:
Adam Ierymenko 2016-06-21 07:59:42 -07:00
parent ca82715bfa
commit 0959d33ba0

View File

@ -123,6 +123,12 @@ public:
* C string in that case. The dest[] array will *never* be unterminated * C string in that case. The dest[] array will *never* be unterminated
* after this call. * after this call.
* *
* Security note: if 'key' is ever directly based on anything that is not
* a hard-code or internally-generated name, it must be checked to ensure
* that the buffer is NULL-terminated since key[] does not take a secondary
* size parameter. In NetworkConfig all keys are hard-coded strings so this
* isn't a problem in the core.
*
* @param key Key to look up * @param key Key to look up
* @param dest Destination buffer * @param dest Destination buffer
* @param destlen Size of destination buffer * @param destlen Size of destination buffer
@ -131,6 +137,7 @@ public:
inline int get(const char *key,char *dest,unsigned int destlen) const inline int get(const char *key,char *dest,unsigned int destlen) const
{ {
const char *p = _d; const char *p = _d;
const char *const eof = p + C;
const char *k; const char *k;
bool esc; bool esc;
int j; int j;
@ -140,11 +147,14 @@ public:
while (*p) { while (*p) {
k = key; k = key;
while (*k) { while ((*k)&&(*p)) {
if (*p != *k) if (*p != *k)
break; break;
++k; ++k;
++p; if (++p == eof) {
dest[0] = (char)0;
return -1;
}
} }
if ((!*k)&&(*p == '=')) { if ((!*k)&&(*p == '=')) {
@ -174,15 +184,26 @@ public:
return j-1; return j-1;
} }
} }
++p; if (++p == eof) {
dest[0] = (char)0;
return -1;
}
} }
dest[j] = (char)0; dest[j] = (char)0;
return j; return j;
} else { } else {
while ((*p)&&(*p != '\r')&&(*p != '\n')) while ((*p)&&(*p != '\r')&&(*p != '\n')) {
++p; if (++p == eof) {
if (*p) dest[0] = (char)0;
++p; return -1;
}
}
if (*p) {
if (++p == eof) {
dest[0] = (char)0;
return -1;
}
}
else break; else break;
} }
} }