diff options
author | Niall O'Higgins <niallo@cvs.openbsd.org> | 2007-01-02 16:43:46 +0000 |
---|---|---|
committer | Niall O'Higgins <niallo@cvs.openbsd.org> | 2007-01-02 16:43:46 +0000 |
commit | e4dd67e23b287074f915425c4632e4bfbc4ae009 (patch) | |
tree | b51e7b0fcf67d34ae1ee21e0084939c1b17f35a5 /usr.bin | |
parent | 74187404662764762470e1cbc6a2f9db1b9fee62 (diff) |
- fix support for checking out binary files.
testing from xsa@ and Igor Sobrado <igor at string1.ciencias.uniovi.es>
ok xsa@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/rcs/diff3.c | 49 | ||||
-rw-r--r-- | usr.bin/rcs/rcs.c | 42 | ||||
-rw-r--r-- | usr.bin/rcs/rcsutil.c | 50 | ||||
-rw-r--r-- | usr.bin/rcs/rcsutil.h | 13 |
4 files changed, 87 insertions, 67 deletions
diff --git a/usr.bin/rcs/diff3.c b/usr.bin/rcs/diff3.c index 99d618e83c1..ee40c32d81a 100644 --- a/usr.bin/rcs/diff3.c +++ b/usr.bin/rcs/diff3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff3.c,v 1.16 2006/10/24 06:22:53 ray Exp $ */ +/* $OpenBSD: diff3.c,v 1.17 2007/01/02 16:43:45 niallo Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. @@ -72,7 +72,7 @@ static const char copyright[] = #ifndef lint static const char rcsid[] = - "$OpenBSD: diff3.c,v 1.16 2006/10/24 06:22:53 ray Exp $"; + "$OpenBSD: diff3.c,v 1.17 2007/01/02 16:43:45 niallo Exp $"; #endif /* not lint */ #include "includes.h" @@ -162,9 +162,12 @@ merge_diff3(char **av, int flags) int argc; char *argv[5], *dp13, *dp23, *path1, *path2, *path3; BUF *b1, *b2, *b3, *d1, *d2, *diffb; + u_char *data, *patch; + size_t dlen, plen; b1 = b2 = b3 = d1 = d2 = diffb = NULL; dp13 = dp23 = path1 = path2 = path3 = NULL; + data = patch = NULL; if ((flags & MERGE_EFLAG) && !(flags & MERGE_OFLAG)) oflag = 0; @@ -228,7 +231,13 @@ merge_diff3(char **av, int flags) rcs_buf_putc(diffb, '\0'); rcs_buf_putc(b1, '\0'); - if ((diffb = rcs_patchfile(b1, diffb, ed_patch_lines)) == NULL) + + plen = rcs_buf_len(diffb); + patch = rcs_buf_release(diffb); + dlen = rcs_buf_len(b1); + data = rcs_buf_release(b1); + + if ((diffb = rcs_patchfile(data, dlen, patch, plen, ed_patch_lines)) == NULL) goto out; if (!(flags & QUIET) && diff3_conflicts != 0) @@ -260,6 +269,10 @@ out: xfree(dp13); if (dp23 != NULL) xfree(dp23); + if (data != NULL) + xfree(data); + if (patch != NULL) + xfree(patch); return (diffb); } @@ -271,9 +284,12 @@ rcs_diff3(RCSFILE *rf, char *workfile, RCSNUM *rev1, RCSNUM *rev2, int flags) char *argv[5], r1[16], r2[16]; char *dp13, *dp23, *path1, *path2, *path3; BUF *b1, *b2, *b3, *d1, *d2, *diffb; + size_t dlen, plen; + u_char *data, *patch; b1 = b2 = b3 = d1 = d2 = diffb = NULL; dp13 = dp23 = path1 = path2 = path3 = NULL; + data = patch = NULL; if ((flags & MERGE_EFLAG) && !(flags & MERGE_OFLAG)) oflag = 0; @@ -346,7 +362,12 @@ rcs_diff3(RCSFILE *rf, char *workfile, RCSNUM *rev1, RCSNUM *rev2, int flags) rcs_buf_putc(diffb, '\0'); rcs_buf_putc(b1, '\0'); - if ((diffb = rcs_patchfile(b1, diffb, ed_patch_lines)) == NULL) + plen = rcs_buf_len(diffb); + patch = rcs_buf_release(diffb); + dlen = rcs_buf_len(b1); + data = rcs_buf_release(b1); + + if ((diffb = rcs_patchfile(data, dlen, patch, plen, ed_patch_lines)) == NULL) goto out; if (!(flags & QUIET) && diff3_conflicts != 0) @@ -378,6 +399,10 @@ out: xfree(dp13); if (dp23 != NULL) xfree(dp23); + if (data != NULL) + xfree(data); + if (patch != NULL) + xfree(patch); return (diffb); } @@ -420,6 +445,7 @@ ed_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) char op, *ep; struct rcs_line *sort, *lp, *dlp, *ndlp, *insert_after; int start, end, i, lineno; + u_char tmp; dlp = TAILQ_FIRST(&(dlines->l_lines)); lp = TAILQ_FIRST(&(plines->l_lines)); @@ -427,10 +453,17 @@ ed_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) end = 0; for (lp = TAILQ_NEXT(lp, l_list); lp != NULL; lp = TAILQ_NEXT(lp, l_list)) { - if (lp->l_line[0] == '\0') - errx(1, "ed_patch_lines"); - op = lp->l_line[strlen(lp->l_line) - 1]; + /* Skip blank lines */ + if (lp->l_len < 2) + continue; + /* NUL-terminate line buffer for strtol() safety. */ + tmp = lp->l_line[lp->l_len - 1]; + lp->l_line[lp->l_len - 1] = '\0'; + /* len - 1 is NUL terminator so we use len - 2 for 'op' */ + op = lp->l_line[lp->l_len - 2]; start = (int)strtol(lp->l_line, &ep, 10); + /* Restore the last byte of the buffer */ + lp->l_line[lp->l_len - 1] = tmp; if (op == 'a') { if (start > dlines->l_nblines || start < 0 || *ep != 'a') @@ -487,7 +520,7 @@ ed_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) if (lp == NULL) errx(1, "ed_patch_lines"); - if (!strcmp(lp->l_line, ".")) + if (!memcmp(lp->l_line, ".", 1)) break; TAILQ_REMOVE(&(plines->l_lines), lp, l_list); diff --git a/usr.bin/rcs/rcs.c b/usr.bin/rcs/rcs.c index eebd59abbfa..8dd596c687b 100644 --- a/usr.bin/rcs/rcs.c +++ b/usr.bin/rcs/rcs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcs.c,v 1.34 2006/12/21 15:37:44 niallo Exp $ */ +/* $OpenBSD: rcs.c,v 1.35 2007/01/02 16:43:45 niallo Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -483,14 +483,8 @@ rcs_write(RCSFILE *rfp) fputc('\n', fp); } fputs("@\ntext\n@", fp); - if (rdp->rd_text != NULL) { + if (rdp->rd_text != NULL) rcs_strprint(rdp->rd_text, rdp->rd_tlen, fp); - - if (rdp->rd_tlen != 0) { - if (rdp->rd_text[rdp->rd_tlen-1] != '\n') - fputc('\n', fp); - } - } fputs("@\n", fp); } (void)fclose(fp); @@ -1038,6 +1032,7 @@ rcs_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) char op, *ep; struct rcs_line *lp, *dlp, *ndlp; int i, lineno, nbln; + u_char tmp; dlp = TAILQ_FIRST(&(dlines->l_lines)); lp = TAILQ_FIRST(&(plines->l_lines)); @@ -1045,14 +1040,21 @@ rcs_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) /* skip first bogus line */ for (lp = TAILQ_NEXT(lp, l_list); lp != NULL; lp = TAILQ_NEXT(lp, l_list)) { + if (lp->l_len < 2) + errx(1, "line too short, RCS patch seems broken"); op = *(lp->l_line); + /* NUL-terminate line buffer for strtol() safety. */ + tmp = lp->l_line[lp->l_len - 1]; + lp->l_line[lp->l_len - 1] = '\0'; lineno = (int)strtol((lp->l_line + 1), &ep, 10); if (lineno > dlines->l_nblines || lineno < 0 || *ep != ' ') errx(1, "invalid line specification in RCS patch"); ep++; nbln = (int)strtol(ep, &ep, 10); - if (nbln < 0 || *ep != '\0') + /* Restore the last byte of the buffer */ + lp->l_line[lp->l_len - 1] = tmp; + if (nbln < 0) errx(1, "invalid line number specification in RCS patch"); @@ -1078,8 +1080,6 @@ rcs_patch_lines(struct rcs_lines *dlines, struct rcs_lines *plines) for (i = 0; (i < nbln) && (dlp != NULL); i++) { ndlp = TAILQ_NEXT(dlp, l_list); TAILQ_REMOVE(&(dlines->l_lines), dlp, l_list); - if (dlp->l_line != NULL) - xfree(dlp->l_line); xfree(dlp); dlp = ndlp; /* last line is gone - reset dlp */ @@ -1134,11 +1134,12 @@ rcs_getrev(RCSFILE *rfp, RCSNUM *frev) { u_int i, numlen; int isbranch, lookonbranch, found; - size_t len; + size_t dlen, plen, len; RCSNUM *crev, *rev, *brev; - BUF *rbuf, *dtext; + BUF *rbuf; struct rcs_delta *rdp = NULL; struct rcs_branch *rb; + u_char *data, *patch; if (rfp->rf_head == NULL) return (NULL); @@ -1244,25 +1245,20 @@ rcs_getrev(RCSFILE *rfp, RCSNUM *frev) return (NULL); } - rcs_buf_putc(rbuf, '\0'); - + plen = rdp->rd_tlen; + dlen = rcs_buf_len(rbuf); + patch = rdp->rd_text; + data = rcs_buf_release(rbuf); /* check if we have parsed this rev's deltatext */ if (rdp->rd_tlen == 0) rcs_parse_deltatexts(rfp, rdp->rd_num); - - dtext = rcs_buf_alloc(len, BUF_AUTOEXT); - rcs_buf_append(dtext, rdp->rd_text, rdp->rd_tlen); - rbuf = rcs_patchfile(rbuf, dtext, rcs_patch_lines); + rbuf = rcs_patchfile(data, dlen, patch, plen, rcs_patch_lines); if (rbuf == NULL) break; } while (rcsnum_cmp(crev, rev, 0) != 0); - if (rcs_buf_getc(rbuf, rcs_buf_len(rbuf)-1) != '\n' && - rbuf != NULL) - rcs_buf_putc(rbuf, '\n'); - return (rbuf); } diff --git a/usr.bin/rcs/rcsutil.c b/usr.bin/rcs/rcsutil.c index 98b7c8741f2..f8b13948210 100644 --- a/usr.bin/rcs/rcsutil.c +++ b/usr.bin/rcs/rcsutil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsutil.c,v 1.23 2006/11/09 21:47:52 millert Exp $ */ +/* $OpenBSD: rcsutil.c,v 1.24 2007/01/02 16:43:45 niallo Exp $ */ /* * Copyright (c) 2005, 2006 Joris Vink <joris@openbsd.org> * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> @@ -472,33 +472,31 @@ rcs_set_description(RCSFILE *file, const char *in) * Split the contents of a file into a list of lines. */ struct rcs_lines * -rcs_splitlines(BUF *fcont) +rcs_splitlines(const u_char *data, size_t len) { u_char *c, *p; struct rcs_lines *lines; struct rcs_line *lp; - size_t i, len; + size_t i, tlen; - len = rcs_buf_len(fcont); lines = xmalloc(sizeof(*lines)); + memset(lines, 0, sizeof(*lines)); TAILQ_INIT(&(lines->l_lines)); - lines->l_nblines = 0; - lines->l_data = rcs_buf_get(fcont); lp = xmalloc(sizeof(*lp)); - lp->l_line = NULL; - lp->l_lineno = 0; + memset(lp, 0, sizeof(*lp)); TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list); - p = c = lines->l_data; - for (i = 0; i < rcs_buf_len(fcont); i++) { - if (*p == '\n' || (i == rcs_buf_len(fcont) - 1 && *c)) { - len = p - c; + p = c = data; + for (i = 0; i < len; i++) { + if (*p == '\n' || (i == len - 1)) { + tlen = p - c; + if (*p == '\n') + tlen++; lp = xmalloc(sizeof(*lp)); - lp->l_line = xmalloc(len + 1); - memcpy(lp->l_line, c, len); - lp->l_line[len] = '\0'; + lp->l_line = c; + lp->l_len = tlen; lp->l_lineno = ++(lines->l_nblines); TAILQ_INSERT_TAIL(&(lines->l_lines), lp, l_list); c = p + 1; @@ -516,29 +514,22 @@ rcs_freelines(struct rcs_lines *lines) while ((lp = TAILQ_FIRST(&(lines->l_lines))) != NULL) { TAILQ_REMOVE(&(lines->l_lines), lp, l_list); - if (lp->l_line != NULL) - xfree(lp->l_line); xfree(lp); } - xfree(lines->l_data); xfree(lines); } BUF * -rcs_patchfile(BUF *data, BUF *patch, +rcs_patchfile(const u_char *data, size_t dlen, const u_char *patch, size_t plen, int (*p)(struct rcs_lines *, struct rcs_lines *)) { struct rcs_lines *dlines, *plines; struct rcs_line *lp; - size_t len; - int lineno; BUF *res; - len = rcs_buf_len(data); - - dlines = rcs_splitlines(data); - plines = rcs_splitlines(patch); + dlines = rcs_splitlines(data, dlen); + plines = rcs_splitlines(patch, plen); if (p(dlines, plines) < 0) { rcs_freelines(dlines); @@ -546,12 +537,11 @@ rcs_patchfile(BUF *data, BUF *patch, return (NULL); } - lineno = 0; - res = rcs_buf_alloc(len, BUF_AUTOEXT); + res = rcs_buf_alloc(1024, BUF_AUTOEXT); TAILQ_FOREACH(lp, &dlines->l_lines, l_list) { - if (lineno != 0) - rcs_buf_fappend(res, "%s\n", lp->l_line); - lineno++; + if (lp->l_line == NULL) + continue; + rcs_buf_append(res, lp->l_line, lp->l_len); } rcs_freelines(dlines); diff --git a/usr.bin/rcs/rcsutil.h b/usr.bin/rcs/rcsutil.h index 647bafd9917..f4c59b9e9d2 100644 --- a/usr.bin/rcs/rcsutil.h +++ b/usr.bin/rcs/rcsutil.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rcsutil.h,v 1.9 2006/11/09 21:47:52 millert Exp $ */ +/* $OpenBSD: rcsutil.h,v 1.10 2007/01/02 16:43:45 niallo Exp $ */ /* * Copyright (c) 2006 Xavier Santolaria <xsa@openbsd.org> * All rights reserved. @@ -30,8 +30,9 @@ #include "rcs.h" struct rcs_line { - char *l_line; + u_char *l_line; int l_lineno; + size_t l_len; TAILQ_ENTRY(rcs_line) l_list; }; @@ -39,7 +40,6 @@ TAILQ_HEAD(rcs_tqh, rcs_line); struct rcs_lines { int l_nblines; - char *l_data; struct rcs_tqh l_lines; }; @@ -60,9 +60,10 @@ int rcs_set_description(RCSFILE *, const char *); void rcs_set_rev(const char *, RCSNUM **); void rcs_setrevstr(char **, char *); void rcs_setrevstr2(char **, char **, char *); -BUF *rcs_patchfile(BUF *, BUF *, - int (*p)(struct rcs_lines *, struct rcs_lines *)); -struct rcs_lines *rcs_splitlines(BUF *); +BUF *rcs_patchfile(const u_char *, size_t, const u_char *, + size_t, + int (*p)(struct rcs_lines *,struct rcs_lines *)); +struct rcs_lines *rcs_splitlines(const u_char *, size_t); void rcs_freelines(struct rcs_lines *); int rcs_yesno(int); struct rcs_argvector *rcs_strsplit(const char *, const char *); |