char *asn_replace(const char *regex, const char *rep, const char *str, mmatic *mm) { int cv[CVS], cvn, rc, br, offset = 0, len = strlen(str); xstr *xs = MMXSTR_CREATE(""); char *mem = malloc(strlen(rep) + 1), *p, *bs; while ((rc = _regex_match(regex, str, len, offset, cv, &cvn)) == 1 && cv[0] >= 0 && cv[1] >= cv[0]) { if (cv[0] >= len) break; dbg(8, "asn_replace(): matched at %d-%d (rc=%d, offset=%d)\n", cv[0], cv[1], rc, offset); /* copy text up to the first match */ xstr_append_size(xs, str+offset, cv[0]-offset); /* replace, handling backreferences */ strcpy(mem, rep); for (bs = p = mem; (bs = strchr(bs, '\\'));) { if (!bs[1] || !isdigit(bs[1])) continue; /* append everything up to \, position bs on the number */ *bs++ = '\0'; xstr_append(xs, p); /* position p on the end of the number + 1 */ for (p = bs; *p && isdigit(*p); p++); /* substitute */ br = atoi(bs); if (br++ > 0 && br <= cvn) { # define IB (2*br - 2) # define IT (2*br - 1) dbg(9, "asn_replace(): appending backreference %d between %d and %d\n", br-1, cv[IB], cv[IT]-1); xstr_append_size(xs, str + cv[IB], cv[IT] - cv[IB]); } else { dbg(1, "asn_replace(): invalid backreference: %d\n", br-1); } bs = p; } /* in no backreferences case, this appends the whole "rep" string */ xstr_append(xs, p); /* start next match after * XXX: pcreapi(3) manual page says "The first element of a pair is set to the offset of the first character in * a substring, and the second is set to the offset of the first character *after* the end of a substring.", but * does not mention that e.g. a pattern of just /$/m will return cv[1] == cv[0]! */ offset = cv[1] + (cv[1] == cv[0]); if (offset >= len) break; } if (offset <= len); xstr_append(xs, str + offset); /* may be just "" */ free(mem); return xs->s; }
static bool readjson_len(struct req *req, int len) { char buf[BUFSIZ]; xstr *xs = xstr_create("", req); json *js; if (len < 0) { while (fgets(buf, sizeof(buf), stdin)) { if (!buf[0] || buf[0] == '\n') break; xstr_append(xs, buf); } } else { int r; while ((r = fread(buf, 1, MIN(len, sizeof(buf)), stdin))) { if (r < 0) { dbg(5, "fread() returned %d, len=%d\n", r, len); break; } /* always appends \0 */ xstr_append_size(xs, buf, r); len -= r; if (len <= 0) break; } } /* eof? */ if (xstr_length(xs) == 0) exit(0); js = json_create(req); req->params = json_parse(js, xstr_string(xs)); return common(req, false); }