| | @@ -115,10 +115,26 @@ |
| 115 | 115 | int nFrom; /* Number of lines in aFrom[] */ |
| 116 | 116 | DLine *aTo; /* File on right side of the diff */ |
| 117 | 117 | int nTo; /* Number of lines in aTo[] */ |
| 118 | 118 | int (*same_fn)(const DLine*,const DLine*); /* comparison function */ |
| 119 | 119 | }; |
| 120 | + |
| 121 | +/* |
| 122 | +** Count the number of lines in the input string. Include the last line |
| 123 | +** in the count even if it lacks the \n terminator. If an empty string |
| 124 | +** is specified, the number of lines is zero. |
| 125 | +*/ |
| 126 | +static int count_lines( |
| 127 | + const char *z, |
| 128 | + int n |
| 129 | +){ |
| 130 | + int nLine; |
| 131 | + const char *zNL, *z2; |
| 132 | + for(nLine=0, z2=z; (zNL = fossil_strchr(z2,-1,'\n'))!=0; z2=zNL+1, nLine++){} |
| 133 | + if( z2[0]!=0 ) nLine++; |
| 134 | + return nLine; |
| 135 | +} |
| 120 | 136 | |
| 121 | 137 | /* |
| 122 | 138 | ** Return an array of DLine objects containing a pointer to the |
| 123 | 139 | ** start of each line and a hash of that line. The lower |
| 124 | 140 | ** bits of the hash store the length of each line. |
| | @@ -140,27 +156,27 @@ |
| 140 | 156 | u64 diffFlags |
| 141 | 157 | ){ |
| 142 | 158 | int nLine, i, k, nn, s, x; |
| 143 | 159 | unsigned int h, h2; |
| 144 | 160 | DLine *a; |
| 145 | | - const char *zNL, *z2; |
| 146 | | - |
| 147 | | - /* Count the number of lines in the input file. Include the last line |
| 148 | | - ** in the count even if it lacks the \n terminator |
| 149 | | - */ |
| 150 | | - for(nLine=0, z2=z; (zNL = strchr(z2,'\n'))!=0; z2=zNL+1, nLine++){} |
| 151 | | - if( z2[0]!=0 ) nLine++; |
| 152 | | - |
| 161 | + const char *zNL; |
| 162 | + |
| 163 | + nLine = count_lines(z, n); |
| 164 | + assert( nLine>0 || z[0]==0 ); |
| 153 | 165 | a = fossil_malloc( sizeof(a[0])*nLine ); |
| 154 | 166 | memset(a, 0, sizeof(a[0])*nLine); |
| 155 | 167 | if( nLine==0 ){ |
| 168 | + if( fossil_strchr(z,n,'\0')!=0 ){ |
| 169 | + fossil_free(a); |
| 170 | + return 0; |
| 171 | + } |
| 156 | 172 | *pnLine = 0; |
| 157 | 173 | return a; |
| 158 | 174 | } |
| 159 | 175 | i = 0; |
| 160 | 176 | do{ |
| 161 | | - zNL = strchr(z,'\n'); |
| 177 | + zNL = fossil_strchr(z,n,'\n'); |
| 162 | 178 | if( zNL==0 ) zNL = z+n; |
| 163 | 179 | nn = (int)(zNL - z); |
| 164 | 180 | if( nn>LENGTH_MASK ){ |
| 165 | 181 | fossil_free(a); |
| 166 | 182 | return 0; |
| | @@ -204,11 +220,11 @@ |
| 204 | 220 | a[i].indent = s; |
| 205 | 221 | a[i].h = h = (h<<LENGTH_MASK_SZ) | (k-s); |
| 206 | 222 | h2 = h % nLine; |
| 207 | 223 | a[i].iNext = a[h2].iHash; |
| 208 | 224 | a[h2].iHash = i+1; |
| 209 | | - z += nn+1; |
| 225 | + z += nn+1; n -= nn+1; |
| 210 | 226 | i++; |
| 211 | 227 | }while( zNL[0] && zNL[1] ); |
| 212 | 228 | assert( i==nLine ); |
| 213 | 229 | |
| 214 | 230 | /* Return results */ |
| 215 | 231 | |