struct bytestring rfc822_header_unfolded_value(struct rfc822_msg *msg, struct rfc822_header *hdr) { struct bytestring raw = rfc822_header_raw_value(msg, hdr); struct bytestring next, rest; int lines = 0; size_t len = 0; if (!hdr->unfolded.ptr) { rest = raw; while (rest.ptr) { get_line(rest, &next, &rest); lines++; len += next.len; } if (lines <= 1) { hdr->unfolded = bytestring(raw.ptr, len); } else { char *unfold = tal_arr(msg, char, len); char *p = unfold; ALLOC_CHECK(unfold, bytestring_NULL); rest = raw; while (rest.ptr) { get_line(rest, &next, &rest); memcpy(p, next.ptr, next.len); p += next.len; } assert(p == (unfold + len)); hdr->unfolded = bytestring(unfold, len); } }
void check_header(struct rfc822_msg *msg, struct rfc822_header *h, const char *name, const char *val, enum rfc822_header_errors experr, int crlf) { enum rfc822_header_errors errs; struct bytestring hname, hvalue, hfull; size_t namelen = strlen(name); size_t valuelen = strlen(val); size_t nln = crlf ? 2 : 1; size_t fulllen = namelen + valuelen + 1 + nln; errs = rfc822_header_errors(msg, h); ok(errs == experr, "Header errors 0x%x != 0x%x", errs, experr); allocation_failure_check(); hname = rfc822_header_raw_name(msg, h); allocation_failure_check(); ok(hname.ptr && bytestring_eq(hname, bytestring_from_string(name)), "Header name \"%.*s\"", (int)hname.len, hname.ptr); hvalue = rfc822_header_raw_value(msg, h); allocation_failure_check(); ok(hvalue.ptr && ((valuelen + nln) == hvalue.len) && (memcmp(val, hvalue.ptr, valuelen) == 0) && (!crlf || (hvalue.ptr[hvalue.len - 2] == '\r')) && (hvalue.ptr[hvalue.len - 1] == '\n'), "Header value"); hfull = rfc822_header_raw_content(msg, h); allocation_failure_check(); ok(hfull.ptr && (fulllen == hfull.len) && (memcmp(name, hfull.ptr, namelen) == 0) && (hfull.ptr[namelen] == ':') && (memcmp(val, hfull.ptr + namelen + 1, valuelen) == 0) && (!crlf || (hfull.ptr[fulllen-2] == '\r')) && (hfull.ptr[fulllen-1] == '\n'), "Full header"); }