|
|
|
#include "scan.h"
|
|
|
|
|
|
|
|
/* parse a netstring, input buffer is in (len bytes).
|
|
|
|
* if parsing is successful:
|
|
|
|
* *dest points to string and *slen is size of string
|
|
|
|
* return number of bytes parsed
|
|
|
|
* else
|
|
|
|
* return 0
|
|
|
|
* Note: *dest will point inside the input buffer!
|
|
|
|
*/
|
|
|
|
size_t scan_netstring(const char* in,size_t len,char** dest,size_t* slen) {
|
|
|
|
/* [len]":"[string]","
|
|
|
|
3:foo,3:bar,4:fini, */
|
|
|
|
unsigned long l;
|
|
|
|
size_t n=scan_ulongn(in,len,&l);
|
|
|
|
if (!n || /* did not start with a number */
|
|
|
|
n+2+l<l || /* overflow */
|
|
|
|
n+2+l>len || /* longer than we have input data */
|
|
|
|
in[n]!=':' || /* syntax error */
|
|
|
|
in[n+l+1]!=',')
|
|
|
|
return 0;
|
|
|
|
*dest=(char*)in+n+1;
|
|
|
|
*slen=l;
|
|
|
|
return n+2+l;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef UNITTEST
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#undef UNITTEST
|
|
|
|
#include "scan_ulongn.c"
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
char buf[]="12:hello world!,";
|
|
|
|
char* s;
|
|
|
|
size_t l;
|
|
|
|
const char* orig;
|
|
|
|
assert(scan_netstring(buf,16,&s,&l)==16 && s==buf+3 && l==12);
|
|
|
|
|
|
|
|
orig="3:foo,"; assert(scan_netstring(orig,6,&s,&l)==6 && s==orig+2 && l==3);
|
|
|
|
orig="4294967295:foo,"; assert(scan_netstring(orig,15,&s,&l)==0);
|
|
|
|
orig="18446744073709551615:foo,"; assert(scan_netstring(orig,25,&s,&l)==0);
|
|
|
|
}
|
|
|
|
#endif
|