1854
{
1855
int i;
1856
char *fixed_buf, *buf, *orig, *target;
1857
+ int preimage_limit;
1858
1858
- if (preimage->nr + try_lno > img->nr)
1859
+ if (preimage->nr + try_lno <= img->nr) {
1860
+ /*
1861
+ * The hunk falls within the boundaries of img.
1862
+ */
1863
+ preimage_limit = preimage->nr;
1864
+ if (match_end && (preimage->nr + try_lno != img->nr))
1865
+ return 0;
1866
+ } else if (ws_error_action == correct_ws_error &&
1867
+ (ws_rule & WS_BLANK_AT_EOF) && match_end) {
1868
+ /*
1869
+ * This hunk that matches at the end extends beyond
1870
+ * the end of img, and we are removing blank lines
1871
+ * at the end of the file. This many lines from the
1872
+ * beginning of the preimage must match with img, and
1873
+ * the remainder of the preimage must be blank.
1874
+ */
1875
+ preimage_limit = img->nr - try_lno;
1876
+ } else {
1877
+ /*
1878
+ * The hunk extends beyond the end of the img and
1879
+ * we are not removing blanks at the end, so we
1880
+ * should reject the hunk at this position.
1881
+ */
1882
return 0;
1883
+ }
1884
1885
if (match_beginning && try_lno)
1886
return 0;
1887
1864
- if (match_end && preimage->nr + try_lno != img->nr)
1865
- return 0;
1866
-
1888
/* Quick hash check */
1868
- for (i = 0; i < preimage->nr; i++)
1889
+ for (i = 0; i < preimage_limit; i++)
1890
if (preimage->line[i].hash != img->line[try_lno + i].hash)
1891
return 0;
1892
1872
- /*
1873
- * Do we have an exact match? If we were told to match
1874
- * at the end, size must be exactly at try+fragsize,
1875
- * otherwise try+fragsize must be still within the preimage,
1876
- * and either case, the old piece should match the preimage
1877
- * exactly.
1878
- */
1879
- if ((match_end
1880
- ? (try + preimage->len == img->len)
1881
- : (try + preimage->len <= img->len)) &&
1882
- !memcmp(img->buf + try, preimage->buf, preimage->len))
1883
- return 1;
1893
+ if (preimage_limit == preimage->nr) {
1894
+ /*
1895
+ * Do we have an exact match? If we were told to match
1896
+ * at the end, size must be exactly at try+fragsize,
1897
+ * otherwise try+fragsize must be still within the preimage,
1898
+ * and either case, the old piece should match the preimage
1899
+ * exactly.
1900
+ */
1901
+ if ((match_end
1902
+ ? (try + preimage->len == img->len)
1903
+ : (try + preimage->len <= img->len)) &&
1904
+ !memcmp(img->buf + try, preimage->buf, preimage->len))
1905
+ return 1;
1906
+ } else {
1907
+ /*
1908
+ * The preimage extends beyond the end of img, so
1909
+ * there cannot be an exact match.
1910
+ *
1911
+ * There must be one non-blank context line that match
1912
+ * a line before the end of img.
1913
+ */
1914
+ char *buf_end;
1915
+
1916
+ buf = preimage->buf;
1917
+ buf_end = buf;
1918
+ for (i = 0; i < preimage_limit; i++)
1919
+ buf_end += preimage->line[i].len;
1920
+
1921
+ for ( ; buf < buf_end; buf++)
1922
+ if (!isspace(*buf))
1923
+ break;
1924
+ if (buf == buf_end)
1925
+ return 0;
1926
+ }
1927
1928
/*
1929
* No exact match. If we are ignoring whitespace, run a line-by-line
1934
size_t imgoff = 0;
1935
size_t preoff = 0;
1936
size_t postlen = postimage->len;
1894
- for (i = 0; i < preimage->nr; i++) {
1937
+ size_t extra_chars;
1938
+ char *preimage_eof;
1939
+ char *preimage_end;
1940
+ for (i = 0; i < preimage_limit; i++) {
1941
size_t prelen = preimage->line[i].len;
1942
size_t imglen = img->line[try_lno+i].len;
1943
1954
* Ok, the preimage matches with whitespace fuzz.
1955
*
1956
* imgoff now holds the true length of the target that
1911
- * matches the preimage. Update the preimage and
1912
- * the common postimage context lines to use the same
1913
- * whitespace as the target.
1957
+ * matches the preimage before the end of the file.
1958
+ *
1959
+ * Count the number of characters in the preimage that fall
1960
+ * beyond the end of the file and make sure that all of them
1961
+ * are whitespace characters. (This can only happen if
1962
+ * we are removing blank lines at the end of the file.)
1963
*/
1915
- fixed_buf = xmalloc(imgoff);
1964
+ buf = preimage_eof = preimage->buf + preoff;
1965
+ for ( ; i < preimage->nr; i++)
1966
+ preoff += preimage->line[i].len;
1967
+ preimage_end = preimage->buf + preoff;
1968
+ for ( ; buf < preimage_end; buf++)
1969
+ if (!isspace(*buf))
1970
+ return 0;
1971
+
1972
+ /*
1973
+ * Update the preimage and the common postimage context
1974
+ * lines to use the same whitespace as the target.
1975
+ * If whitespace is missing in the target (i.e.
1976
+ * if the preimage extends beyond the end of the file),
1977
+ * use the whitespace from the preimage.
1978
+ */
1979
+ extra_chars = preimage_end - preimage_eof;
1980
+ fixed_buf = xmalloc(imgoff + extra_chars);
1981
memcpy(fixed_buf, img->buf + try, imgoff);
1982
+ memcpy(fixed_buf + imgoff, preimage_eof, extra_chars);
1983
+ imgoff += extra_chars;
1984
update_pre_post_images(preimage, postimage,
1985
fixed_buf, imgoff, postlen);
1986
return 1;
1994
* it might with whitespace fuzz. We haven't been asked to
1995
* ignore whitespace, we were asked to correct whitespace
1996
* errors, so let's try matching after whitespace correction.
1997
+ *
1998
+ * The preimage may extend beyond the end of the file,
1999
+ * but in this loop we will only handle the part of the
2000
+ * preimage that falls within the file.
2001
*/
2002
fixed_buf = xmalloc(preimage->len + 1);
2003
buf = fixed_buf;
2004
orig = preimage->buf;
2005
target = img->buf + try;
1935
- for (i = 0; i < preimage->nr; i++) {
2006
+ for (i = 0; i < preimage_limit; i++) {
2007
size_t fixlen; /* length after fixing the preimage */
2008
size_t oldlen = preimage->line[i].len;
2009
size_t tgtlen = img->line[try_lno + i].len;
2043
target += tgtlen;
2044
}
2045
2046
+
2047
+ /*
2048
+ * Now handle the lines in the preimage that falls beyond the
2049
+ * end of the file (if any). They will only match if they are
2050
+ * empty or only contain whitespace (if WS_BLANK_AT_EOL is
2051
+ * false).
2052
+ */
2053
+ for ( ; i < preimage->nr; i++) {
2054
+ size_t fixlen; /* length after fixing the preimage */
2055
+ size_t oldlen = preimage->line[i].len;
2056
+ int j;
2057
+
2058
+ /* Try fixing the line in the preimage */
2059
+ fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
2060
+
2061
+ for (j = 0; j < fixlen; j++)
2062
+ if (!isspace(buf[j]))
2063
+ goto unmatch_exit;
2064
+
2065
+ orig += oldlen;
2066
+ buf += fixlen;
2067
+ }
2068
+
2069
/*
2070
* Yes, the preimage is based on an older version that still
2071
* has whitespace breakages unfixed, and fixing them makes the
2182
int i, nr;
2183
size_t remove_count, insert_count, applied_at = 0;
2184
char *result;
2185
+ int preimage_limit;
2186
+
2187
+ /*
2188
+ * If we are removing blank lines at the end of img,
2189
+ * the preimage may extend beyond the end.
2190
+ * If that is the case, we must be careful only to
2191
+ * remove the part of the preimage that falls within
2192
+ * the boundaries of img. Initialize preimage_limit
2193
+ * to the number of lines in the preimage that falls
2194
+ * within the boundaries.
2195
+ */
2196
+ preimage_limit = preimage->nr;
2197
+ if (preimage_limit > img->nr - applied_pos)
2198
+ preimage_limit = img->nr - applied_pos;
2199
2200
for (i = 0; i < applied_pos; i++)
2201
applied_at += img->line[i].len;
2202
2203
remove_count = 0;
2096
- for (i = 0; i < preimage->nr; i++)
2204
+ for (i = 0; i < preimage_limit; i++)
2205
remove_count += img->line[applied_pos + i].len;
2206
insert_count = postimage->len;
2207
2218
result[img->len] = '\0';
2219
2220
/* Adjust the line table */
2113
- nr = img->nr + postimage->nr - preimage->nr;
2114
- if (preimage->nr < postimage->nr) {
2221
+ nr = img->nr + postimage->nr - preimage_limit;
2222
+ if (preimage_limit < postimage->nr) {
2223
/*
2224
* NOTE: this knows that we never call remove_first_line()
2225
* on anything other than pre/post image.
2227
img->line = xrealloc(img->line, nr * sizeof(*img->line));
2228
img->line_allocated = img->line;
2229
}
2122
- if (preimage->nr != postimage->nr)
2230
+ if (preimage_limit != postimage->nr)
2231
memmove(img->line + applied_pos + postimage->nr,
2124
- img->line + applied_pos + preimage->nr,
2125
- (img->nr - (applied_pos + preimage->nr)) *
2232
+ img->line + applied_pos + preimage_limit,
2233
+ (img->nr - (applied_pos + preimage_limit)) *
2234
sizeof(*img->line));
2235
memcpy(img->line + applied_pos,
2236
postimage->line,
2426
2427
if (applied_pos >= 0) {
2428
if (new_blank_lines_at_end &&
2321
- preimage.nr + applied_pos == img->nr &&
2429
+ preimage.nr + applied_pos >= img->nr &&
2430
(ws_rule & WS_BLANK_AT_EOF) &&
2431
ws_error_action != nowarn_ws_error) {
2432
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);