Fossil SCM

Fix the checksum routine in the delta logic so that it works correctly even if the input size is zero.

drh 2024-11-18 17:40 trunk
Commit ec5e2919a71c7c2439320f9b7225936f79912c29961ed178c07f12b9d1ba4f27
1 file changed +50 -48
+50 -48
--- src/delta.c
+++ src/delta.c
@@ -225,59 +225,61 @@
225225
** of four bytes.
226226
*/
227227
static unsigned int checksum(const char *zIn, size_t N){
228228
static const int byteOrderTest = 1;
229229
const unsigned char *z = (const unsigned char *)zIn;
230
- const unsigned char *zEnd = (const unsigned char*)&zIn[N&~3];
231230
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
+ }
279281
}
280282
return sum;
281283
}
282284
283285
/*
284286
--- 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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button