diff --git a/textcode/scan_base64.3 b/textcode/scan_base64.3 index ef6e617..c57d1c9 100644 --- a/textcode/scan_base64.3 +++ b/textcode/scan_base64.3 @@ -18,17 +18,19 @@ those and return the decoded data until then. base64 works by taking 3 bytes of binary input and converting them into 4 bytes of printable ASCII. If the input ends in the middle of a base64 -4-byte-tuple, scan_base64 will disregard it. +4-byte-tuple, scan_base64 will disregard the whole tuple. Many base64 variants demand padding in the last block. Some don't. This implementation will consume padding if it is there, but will not complain if it is not. +dest can be NULL. destlen can be NULL. + .SH "RETURN VALUE" scan_base64 returns the number of bytes successfully scanned and processed from src. .SH EXAMPLES -scan_base64("Zm5vcmQ=",buf,&i) -> return 8, i=5, buf="fnord" +scan_base64("%9FYO return 8, i=5, buf="fnord" .SH "SEE ALSO" scan_xlong(3), scan_8long(3), fmt_ulong(3) diff --git a/textcode/scan_uuencoded.3 b/textcode/scan_uuencoded.3 new file mode 100644 index 0000000..36547df --- /dev/null +++ b/textcode/scan_uuencoded.3 @@ -0,0 +1,36 @@ +.TH scan_uuencoded 3 +.SH NAME +scan_uuencoded \- decode uuencoded data +.SH SYNTAX +.B #include + +size_t \fBscan_uuencoded\fP(const char *\fIsrc\fR,char *\fIdest\fR,size_t* \fIdestlen\fR); + +.SH DESCRIPTION +scan_uuencoded decodes uuencoded data from src into dest. +It will stop when it encountes any non-valid input characters. +It will then write the number of decoded bytes in dest into *destlen, +and return the number of bytes decoded from src. + +Note that real world uuencoded data is sometimes permitted to +contain whitespace characters or new lines. This function will not allow +those and return the decoded data until then. + +uudecoding works on lines, and the first byte in each line contains the +length of the line (encoded). scan_uuencoded expects one such line as +input, and it will decode all the bytes in it. + +uuencoded data can contain bytes from 0x21 to 0x96, which means it is +not "string safe" (can contain single and double quotes and backslash). + +dest can be NULL. destlen can be NULL. + +.SH "RETURN VALUE" +scan_uuencoded returns the number of bytes successfully scanned and +processed from src. + +.SH EXAMPLES +scan_uuencoded("&9FYO return 9, i=5, buf="fnord" + +.SH "SEE ALSO" +scan_xlong(3), scan_8long(3), fmt_ulong(3) diff --git a/textcode/scan_uuencoded.c b/textcode/scan_uuencoded.c index 1a2af7a..af6f2f0 100644 --- a/textcode/scan_uuencoded.c +++ b/textcode/scan_uuencoded.c @@ -4,7 +4,7 @@ size_t scan_uuencoded(const char *src,char *dest,size_t *destlen) { size_t len; size_t tmp; register const unsigned char* s=(const unsigned char*) src; - const char* orig=dest; + size_t i=0; if ((len=*s-' ')>64) return 0; len&=63; ++s; @@ -15,10 +15,27 @@ size_t scan_uuencoded(const char *src,char *dest,size_t *destlen) { (((s[2]-' ')&077) << (1*6)) + (((s[3]-' ')&077)); s+=4; - if (len) { *dest=tmp>>16; ++dest; --len; } - if (len) { *dest=tmp>>8; ++dest; --len; } - if (len) { *dest=tmp&0xff; ++dest; --len; } + if (len) { if (dest) dest[i++]=tmp>>16; --len; } + if (len) { if (dest) dest[i++]=tmp>>8; --len; } + if (len) { if (dest) dest[i++]=tmp&0xff; --len; } } - *destlen=dest-orig; + if (destlen) *destlen=i; return (const char*)s-src; } + +#ifdef UNITTEST + +#include +#include +#include + +int main() { + char buf[100]; + size_t i; + memset(buf,0,100); + assert(scan_uuencoded("&9FYO