Module: kamailio
Branch: master
Commit: d6a34eee893a47450650ea29671e80dbffc03c8f
URL:
https://github.com/kamailio/kamailio/commit/d6a34eee893a47450650ea29671e80d…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: 2021-12-01T09:34:28+01:00
core: reworked string-number conversion to catch out of limits values
---
Modified: src/core/ut.h
---
Diff:
https://github.com/kamailio/kamailio/commit/d6a34eee893a47450650ea29671e80d…
Patch:
https://github.com/kamailio/kamailio/commit/d6a34eee893a47450650ea29671e80d…
---
diff --git a/src/core/ut.h b/src/core/ut.h
index 9b899a94e7..44bd0e75c7 100644
--- a/src/core/ut.h
+++ b/src/core/ut.h
@@ -627,37 +627,43 @@ static inline void strlower(str* _s)
}
}
-
-#define str2unval(_s, _r, _vmax) do { \
- int i; \
- if (_r == NULL) return -1; \
+#define str2unval(_s, _r, _vtype, _vmax) do { \
+ _vtype limitmul; \
+ int i, c, limitrst; \
+ if((_s == NULL) || (_r == NULL) || (_s->len < 0) || (_s->s == NULL)) { \
+ return -1; \
+ } \
*_r = 0; \
- if (_s == NULL) return -1; \
- if (_s->len < 0) return -1; \
- if (_s->s == NULL) return -1; \
- for(i = 0; i < _s->len; i++) { \
- if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) { \
- if(*_r > _vmax/10) { \
- return -1; \
- } \
- *_r *= 10; \
- if(*_r > _vmax - (_s->s[i] - '0')) { \
- return -1; \
- } \
- *_r += _s->s[i] - '0'; \
- } else { \
+ i = 0; \
+ if (_s->s[0] == '+') { \
+ i++; \
+ } \
+ limitmul = _vmax / 10; \
+ limitrst = _vmax % 10; \
+ for(; i < _s->len; i++) { \
+ c = (unsigned char)_s->s[i]; \
+ if (c < '0' || c > '9') { \
+ return -1; \
+ } \
+ c -= '0'; \
+ if (*_r > limitmul || (*_r == limitmul && c > limitrst)) { \
+ *_r = _vmax; \
return -1; \
+ } else { \
+ *_r *= 10; \
+ *_r += c; \
} \
} \
return 0; \
} while(0)
+
/*
* Convert an str to unsigned long
*/
static inline int str2ulong(str* _s, unsigned long* _r)
{
- str2unval(_s, _r, ULONG_MAX);
+ str2unval(_s, _r, long, ULONG_MAX);
}
/*
@@ -665,56 +671,69 @@ static inline int str2ulong(str* _s, unsigned long* _r)
*/
static inline int str2int(str* _s, unsigned int* _r)
{
- str2unval(_s, _r, UINT_MAX);
+ str2unval(_s, _r, int, UINT_MAX);
}
-#define str2snval(_s, _r, _vmin, _vmax) do { \
- int i; \
- int sign; \
- long long ll; \
- if (_s == NULL) return -1; \
- if (_r == NULL) return -1; \
- if (_s->len < 0) return -1; \
- if (_s->s == NULL) return -1; \
+
+#define str2snval(_s, _r, _vtype, _vmin, _vmax) do { \
+ _vtype limitmul; \
+ int i, c, neg, limitrst; \
+ if((_s == NULL) || (_r == NULL) || (_s->len < 0) || (_s->s == NULL)) { \
+ return -1; \
+ } \
*_r = 0; \
- sign = 1; \
+ neg = 0; \
i = 0; \
if (_s->s[0] == '+') { \
i++; \
} else if (_s->s[0] == '-') { \
- sign = -1; \
+ neg = 1; \
i++; \
} \
+ limitmul = neg ? _vmin : _vmax; \
+ limitrst = limitmul % 10; \
+ limitmul /= 10; \
+ if (neg) { \
+ if (limitrst > 0) { \
+ limitrst -= 10; \
+ limitmul += 1; \
+ } \
+ limitrst = -limitrst; \
+ } \
for(; i < _s->len; i++) { \
- if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) { \
- if(*_r > _vmax/10) { \
+ c = (unsigned char)_s->s[i]; \
+ if (c < '0' || c > '9') { \
+ return -1; \
+ } \
+ c -= '0'; \
+ if (neg) { \
+ if (*_r < limitmul || (*_r == limitmul && c > limitrst)) { \
+ *_r = _vmin; \
return -1; \
+ } else { \
+ *_r *= 10; \
+ *_r -= c; \
} \
- *_r *= 10; \
- if(*_r > _vmax - (_s->s[i] - '0')) { \
+ } else { \
+ if (*_r > limitmul || (*_r == limitmul && c > limitrst)) { \
+ *_r = _vmax; \
return -1; \
+ } else { \
+ *_r *= 10; \
+ *_r += c; \
} \
- *_r += _s->s[i] - '0'; \
- } else { \
- return -1; \
} \
} \
- if(sign < 0) { \
- ll = (long long)(*_r) * sign; \
- if(ll < _vmin) { \
- return -1; \
- } \
- *_r *= sign; \
- } \
return 0; \
} while(0)
+
/*
* Convert an str to signed long
*/
static inline int str2slong(str* _s, long* _r)
{
- str2snval(_s, _r, LONG_MIN, LONG_MAX);
+ str2snval(_s, _r, long, LONG_MIN, LONG_MAX);
}
@@ -723,7 +742,7 @@ static inline int str2slong(str* _s, long* _r)
*/
static inline int str2sint(str* _s, int* _r)
{
- str2snval(_s, _r, INT_MIN, INT_MAX);
+ str2snval(_s, _r, int, INT_MIN, INT_MAX);
}