=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/rcs/rcs.c,v retrieving revision 1.27 retrieving revision 1.28 diff -c -r1.27 -r1.28 *** src/usr.bin/rcs/rcs.c 2006/07/27 02:58:31 1.27 --- src/usr.bin/rcs/rcs.c 2006/07/27 04:23:37 1.28 *************** *** 1,4 **** ! /* $OpenBSD: rcs.c,v 1.27 2006/07/27 02:58:31 deraadt Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. --- 1,4 ---- ! /* $OpenBSD: rcs.c,v 1.28 2006/07/27 04:23:37 ray Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. *************** *** 2567,2581 **** static BUF * rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode) { ! ptrdiff_t c_offset, sizdiff, start_offset; ! size_t i; int kwtype; u_int j, found; ! u_char *c, *data, *kwstr, *start, *end, *tbuf, *fin; char expbuf[256], buf[256]; struct tm tb; char *fmt; ! size_t len, tbuflen; kwtype = 0; kwstr = NULL; --- 2567,2580 ---- static BUF * rcs_expand_keywords(char *rcsfile, struct rcs_delta *rdp, BUF *bp, int mode) { ! BUF *newbuf; int kwtype; u_int j, found; ! u_char *c, *kwstr, *start, *end, *fin; char expbuf[256], buf[256]; struct tm tb; char *fmt; ! size_t len; kwtype = 0; kwstr = NULL; *************** *** 2591,2620 **** c = rcs_buf_get(bp); found = 0; ! for (i = 0; i < len; i++) { ! if (*c == '$') { ! c++; ! i++; ! for (j = 0; j < RCS_NKWORDS; j++) { ! if (!strncmp(c, rcs_expkw[j].kw_str, ! strlen(rcs_expkw[j].kw_str))) { ! found = 1; ! kwstr = rcs_expkw[j].kw_str; ! kwtype = rcs_expkw[j].kw_type; ! break; ! } ! } ! } ! c++; ! } ! if (found == 0) ! return (bp); ! rcs_buf_putc(bp, '\0'); ! data = rcs_buf_release(bp); ! c = data; ! fin = c + len; ! len++; /* * Keyword formats: --- 2590,2600 ---- c = rcs_buf_get(bp); found = 0; ! /* Final character in buffer. */ ! fin = c + len - 1; ! /* If no keywords are found, return original buffer. */ ! newbuf = bp; /* * Keyword formats: *************** *** 2623,2631 **** */ for (; c < fin; c++) { if (*c == '$') { /* remember start of this possible keyword */ start = c; - start_offset = start - data; /* first following character has to be alphanumeric */ c++; --- 2603,2613 ---- */ for (; c < fin; c++) { if (*c == '$') { + BUF *tmpbuf; + size_t clen; + /* remember start of this possible keyword */ start = c; /* first following character has to be alphanumeric */ c++; *************** *** 2634,2647 **** continue; } /* look for any matching keywords */ found = 0; for (j = 0; j < RCS_NKWORDS; j++) { ! if (!strncmp(c, rcs_expkw[j].kw_str, ! strlen(rcs_expkw[j].kw_str))) { found = 1; kwstr = rcs_expkw[j].kw_str; kwtype = rcs_expkw[j].kw_type; break; } } --- 2616,2641 ---- continue; } + /* Number of characters between c and fin, inclusive. */ + clen = fin - c + 1; + /* look for any matching keywords */ found = 0; for (j = 0; j < RCS_NKWORDS; j++) { ! size_t kwlen; ! ! kwlen = strlen(rcs_expkw[j].kw_str); ! /* ! * kwlen must be less than clen since clen ! * includes either a terminating `$' or a `:'. ! */ ! if (kwlen < clen && ! memcmp(c, rcs_expkw[j].kw_str, kwlen) == 0 && ! (c[kwlen] == '$' || c[kwlen] == ':')) { found = 1; kwstr = rcs_expkw[j].kw_str; kwtype = rcs_expkw[j].kw_type; + c += kwlen; break; } } *************** *** 2652,2671 **** continue; } - /* next character has to be ':' or '$' */ - c += strlen(kwstr); - if (*c != ':' && *c != '$') { - c = start; - continue; - } - /* * if the next character was ':' we need to look for * an '$' before the end of the line to be sure it is * in fact a keyword. */ if (*c == ':') { ! while (*c++) { if (*c == '$' || *c == '\n') break; } --- 2646,2658 ---- continue; } /* * if the next character was ':' we need to look for * an '$' before the end of the line to be sure it is * in fact a keyword. */ if (*c == ':') { ! for (; c <= fin; ++c) { if (*c == '$' || *c == '\n') break; } *************** *** 2675,2681 **** continue; } } - c_offset = c - data; end = c + 1; /* start constructing the expansion */ --- 2662,2667 ---- *************** *** 2755,2792 **** if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf)) errx(1, "rcs_expand_keywords: string truncated"); ! sizdiff = strlen(expbuf) - (end - start); ! tbuflen = fin - end; ! tbuf = xmalloc(tbuflen); ! memcpy(tbuf, end, tbuflen); ! /* only realloc if we have to */ ! if (sizdiff > 0) { ! char *newdata; ! len += sizdiff; ! newdata = xrealloc(data, 1, len); ! data = newdata; ! /* ! * ensure string pointers are not invalidated ! * after realloc() ! */ ! start = data + start_offset; ! fin = data + len; ! c = data + c_offset; ! } ! memcpy(start, expbuf, strlen(expbuf) + 1); ! start += strlen(expbuf); ! memcpy(start, tbuf, tbuflen); ! xfree(tbuf); ! c = start + strlen(expbuf); } } ! bp = rcs_buf_alloc(len - 1, BUF_AUTOEXT); ! rcs_buf_set(bp, data, len - 1, 0); ! xfree(data); ! ! return (bp); } /* --- 2741,2769 ---- if (strlcat(expbuf, "$", sizeof(expbuf)) >= sizeof(expbuf)) errx(1, "rcs_expand_keywords: string truncated"); ! /* Concatenate everything together. */ ! tmpbuf = rcs_buf_alloc(len + strlen(expbuf), BUF_AUTOEXT); ! /* Append everything before keyword. */ ! rcs_buf_append(tmpbuf, rcs_buf_get(newbuf), ! start - (unsigned char *)rcs_buf_get(newbuf)); ! /* Append keyword. */ ! rcs_buf_append(tmpbuf, expbuf, strlen(expbuf)); ! /* Point c to end of keyword. */ ! c = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1; ! /* Append everything after keyword. */ ! rcs_buf_append(tmpbuf, end, ! ((unsigned char *)rcs_buf_get(newbuf) + rcs_buf_len(newbuf)) - end); ! /* Point fin to end of data. */ ! fin = rcs_buf_get(tmpbuf) + rcs_buf_len(tmpbuf) - 1; ! /* tmpbuf is now ready, free old newbuf if allocated here. */ ! if (newbuf != bp) ! rcs_buf_free(newbuf); ! newbuf = tmpbuf; } } ! return (newbuf); } /*