Fossil SCM
Fix the checksum routine in the delta logic so that it works correctly even if the input size is zero.
Commit
ec5e2919a71c7c2439320f9b7225936f79912c29961ed178c07f12b9d1ba4f27
Parent
5493cc7bb598466…
1 file changed
+50
-48
+50
-48
| --- src/delta.c | ||
| +++ src/delta.c | ||
| @@ -225,59 +225,61 @@ | ||
| 225 | 225 | ** of four bytes. |
| 226 | 226 | */ |
| 227 | 227 | static unsigned int checksum(const char *zIn, size_t N){ |
| 228 | 228 | static const int byteOrderTest = 1; |
| 229 | 229 | const unsigned char *z = (const unsigned char *)zIn; |
| 230 | - const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3]; | |
| 231 | 230 | unsigned sum = 0; |
| 232 | - assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */ | |
| 233 | - if( 0==*(char*)&byteOrderTest ){ | |
| 234 | - /* This is a big-endian machine */ | |
| 235 | - while( z<zEnd ){ | |
| 236 | - sum += *(unsigned*)z; | |
| 237 | - z += 4; | |
| 238 | - } | |
| 239 | - }else{ | |
| 240 | - /* A little-endian machine */ | |
| 241 | -#if GCC_VERSION>=4003000 | |
| 242 | - while( z<zEnd ){ | |
| 243 | - sum += __builtin_bswap32(*(unsigned*)z); | |
| 244 | - z += 4; | |
| 245 | - } | |
| 246 | -#elif defined(_MSC_VER) && _MSC_VER>=1300 | |
| 247 | - while( z<zEnd ){ | |
| 248 | - sum += _byteswap_ulong(*(unsigned*)z); | |
| 249 | - z += 4; | |
| 250 | - } | |
| 251 | -#else | |
| 252 | - unsigned sum0 = 0; | |
| 253 | - unsigned sum1 = 0; | |
| 254 | - unsigned sum2 = 0; | |
| 255 | - while(N >= 16){ | |
| 256 | - sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); | |
| 257 | - sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); | |
| 258 | - sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); | |
| 259 | - sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]); | |
| 260 | - z += 16; | |
| 261 | - N -= 16; | |
| 262 | - } | |
| 263 | - while(N >= 4){ | |
| 264 | - sum0 += z[0]; | |
| 265 | - sum1 += z[1]; | |
| 266 | - sum2 += z[2]; | |
| 267 | - sum += z[3]; | |
| 268 | - z += 4; | |
| 269 | - N -= 4; | |
| 270 | - } | |
| 271 | - sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); | |
| 272 | -#endif | |
| 273 | - } | |
| 274 | - switch(N&3){ | |
| 275 | - case 3: sum += (z[2] << 8); | |
| 276 | - case 2: sum += (z[1] << 16); | |
| 277 | - case 1: sum += (z[0] << 24); | |
| 278 | - default: ; | |
| 231 | + if( N>0 ){ | |
| 232 | + const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3]; | |
| 233 | + assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */ | |
| 234 | + if( 0==*(char*)&byteOrderTest ){ | |
| 235 | + /* This is a big-endian machine */ | |
| 236 | + while( z<zEnd ){ | |
| 237 | + sum += *(unsigned*)z; | |
| 238 | + z += 4; | |
| 239 | + } | |
| 240 | + }else{ | |
| 241 | + /* A little-endian machine */ | |
| 242 | + #if GCC_VERSION>=4003000 | |
| 243 | + while( z<zEnd ){ | |
| 244 | + sum += __builtin_bswap32(*(unsigned*)z); | |
| 245 | + z += 4; | |
| 246 | + } | |
| 247 | + #elif defined(_MSC_VER) && _MSC_VER>=1300 | |
| 248 | + while( z<zEnd ){ | |
| 249 | + sum += _byteswap_ulong(*(unsigned*)z); | |
| 250 | + z += 4; | |
| 251 | + } | |
| 252 | + #else | |
| 253 | + unsigned sum0 = 0; | |
| 254 | + unsigned sum1 = 0; | |
| 255 | + unsigned sum2 = 0; | |
| 256 | + while(N >= 16){ | |
| 257 | + sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); | |
| 258 | + sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); | |
| 259 | + sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); | |
| 260 | + sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]); | |
| 261 | + z += 16; | |
| 262 | + N -= 16; | |
| 263 | + } | |
| 264 | + while(N >= 4){ | |
| 265 | + sum0 += z[0]; | |
| 266 | + sum1 += z[1]; | |
| 267 | + sum2 += z[2]; | |
| 268 | + sum += z[3]; | |
| 269 | + z += 4; | |
| 270 | + N -= 4; | |
| 271 | + } | |
| 272 | + sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); | |
| 273 | + #endif | |
| 274 | + } | |
| 275 | + switch(N&3){ | |
| 276 | + case 3: sum += (z[2] << 8); | |
| 277 | + case 2: sum += (z[1] << 16); | |
| 278 | + case 1: sum += (z[0] << 24); | |
| 279 | + default: ; | |
| 280 | + } | |
| 279 | 281 | } |
| 280 | 282 | return sum; |
| 281 | 283 | } |
| 282 | 284 | |
| 283 | 285 | /* |
| 284 | 286 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -225,59 +225,61 @@ | |
| 225 | ** of four bytes. |
| 226 | */ |
| 227 | static unsigned int checksum(const char *zIn, size_t N){ |
| 228 | static const int byteOrderTest = 1; |
| 229 | const unsigned char *z = (const unsigned char *)zIn; |
| 230 | const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3]; |
| 231 | unsigned sum = 0; |
| 232 | assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */ |
| 233 | if( 0==*(char*)&byteOrderTest ){ |
| 234 | /* This is a big-endian machine */ |
| 235 | while( z<zEnd ){ |
| 236 | sum += *(unsigned*)z; |
| 237 | z += 4; |
| 238 | } |
| 239 | }else{ |
| 240 | /* A little-endian machine */ |
| 241 | #if GCC_VERSION>=4003000 |
| 242 | while( z<zEnd ){ |
| 243 | sum += __builtin_bswap32(*(unsigned*)z); |
| 244 | z += 4; |
| 245 | } |
| 246 | #elif defined(_MSC_VER) && _MSC_VER>=1300 |
| 247 | while( z<zEnd ){ |
| 248 | sum += _byteswap_ulong(*(unsigned*)z); |
| 249 | z += 4; |
| 250 | } |
| 251 | #else |
| 252 | unsigned sum0 = 0; |
| 253 | unsigned sum1 = 0; |
| 254 | unsigned sum2 = 0; |
| 255 | while(N >= 16){ |
| 256 | sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); |
| 257 | sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); |
| 258 | sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); |
| 259 | sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]); |
| 260 | z += 16; |
| 261 | N -= 16; |
| 262 | } |
| 263 | while(N >= 4){ |
| 264 | sum0 += z[0]; |
| 265 | sum1 += z[1]; |
| 266 | sum2 += z[2]; |
| 267 | sum += z[3]; |
| 268 | z += 4; |
| 269 | N -= 4; |
| 270 | } |
| 271 | sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); |
| 272 | #endif |
| 273 | } |
| 274 | switch(N&3){ |
| 275 | case 3: sum += (z[2] << 8); |
| 276 | case 2: sum += (z[1] << 16); |
| 277 | case 1: sum += (z[0] << 24); |
| 278 | default: ; |
| 279 | } |
| 280 | return sum; |
| 281 | } |
| 282 | |
| 283 | /* |
| 284 |
| --- src/delta.c | |
| +++ src/delta.c | |
| @@ -225,59 +225,61 @@ | |
| 225 | ** of four bytes. |
| 226 | */ |
| 227 | static unsigned int checksum(const char *zIn, size_t N){ |
| 228 | static const int byteOrderTest = 1; |
| 229 | const unsigned char *z = (const unsigned char *)zIn; |
| 230 | unsigned sum = 0; |
| 231 | if( N>0 ){ |
| 232 | const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3]; |
| 233 | assert( (z - (const unsigned char*)0)%4==0 ); /* Four-byte alignment */ |
| 234 | if( 0==*(char*)&byteOrderTest ){ |
| 235 | /* This is a big-endian machine */ |
| 236 | while( z<zEnd ){ |
| 237 | sum += *(unsigned*)z; |
| 238 | z += 4; |
| 239 | } |
| 240 | }else{ |
| 241 | /* A little-endian machine */ |
| 242 | #if GCC_VERSION>=4003000 |
| 243 | while( z<zEnd ){ |
| 244 | sum += __builtin_bswap32(*(unsigned*)z); |
| 245 | z += 4; |
| 246 | } |
| 247 | #elif defined(_MSC_VER) && _MSC_VER>=1300 |
| 248 | while( z<zEnd ){ |
| 249 | sum += _byteswap_ulong(*(unsigned*)z); |
| 250 | z += 4; |
| 251 | } |
| 252 | #else |
| 253 | unsigned sum0 = 0; |
| 254 | unsigned sum1 = 0; |
| 255 | unsigned sum2 = 0; |
| 256 | while(N >= 16){ |
| 257 | sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]); |
| 258 | sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]); |
| 259 | sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]); |
| 260 | sum += ((unsigned)z[3] + z[7] + z[11]+ z[15]); |
| 261 | z += 16; |
| 262 | N -= 16; |
| 263 | } |
| 264 | while(N >= 4){ |
| 265 | sum0 += z[0]; |
| 266 | sum1 += z[1]; |
| 267 | sum2 += z[2]; |
| 268 | sum += z[3]; |
| 269 | z += 4; |
| 270 | N -= 4; |
| 271 | } |
| 272 | sum += (sum2 << 8) + (sum1 << 16) + (sum0 << 24); |
| 273 | #endif |
| 274 | } |
| 275 | switch(N&3){ |
| 276 | case 3: sum += (z[2] << 8); |
| 277 | case 2: sum += (z[1] << 16); |
| 278 | case 1: sum += (z[0] << 24); |
| 279 | default: ; |
| 280 | } |
| 281 | } |
| 282 | return sum; |
| 283 | } |
| 284 | |
| 285 | /* |
| 286 |