Last active
July 20, 2023 06:55
-
-
Save ikazuhiro/4e94018c007fb21cf2b9b14e9b0bc97a to your computer and use it in GitHub Desktop.
QDBM 1.8.78 bug fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 442eebedb9800b7140f154235af573bc0ef95249 Mon Sep 17 00:00:00 2001 | |
From: Kazuhiro Ito <[email protected]> | |
Date: Tue, 27 Jul 2021 19:36:37 +0900 | |
Subject: [PATCH 1/4] Use unsigned integers to calculate hash | |
Overflow of signed integers is undefined bahavior. | |
--- | |
cabin.c | 39 +++++++++++++++++----------------- | |
depot.c | 66 ++++++++++++++++++++++++++++----------------------------- | |
2 files changed, 52 insertions(+), 53 deletions(-) | |
diff --git a/cabin.c b/cabin.c | |
index eecc328..e084440 100644 | |
--- a/cabin.c | |
+++ b/cabin.c | |
@@ -79,29 +79,28 @@ | |
} while(FALSE) | |
/* get the first hash value */ | |
-#define CB_FIRSTHASH(CB_res, CB_kbuf, CB_ksiz) \ | |
- do { \ | |
- const unsigned char *_CB_p; \ | |
- int _CB_ksiz; \ | |
- _CB_p = (const unsigned char *)(CB_kbuf); \ | |
- _CB_ksiz = CB_ksiz; \ | |
- for((CB_res) = 19780211; _CB_ksiz--;){ \ | |
- (CB_res) = (CB_res) * 37 + *(_CB_p)++; \ | |
- } \ | |
- (CB_res) &= INT_MAX; \ | |
+#define CB_FIRSTHASH(CB_res, CB_kbuf, CB_ksiz) \ | |
+ do { \ | |
+ const unsigned char *_CB_p = (const unsigned char *)(CB_kbuf); \ | |
+ int _CB_ksiz = (CB_ksiz); \ | |
+ unsigned int _CB_res; \ | |
+ for(_CB_res = 19780211; _CB_ksiz--; _CB_p++){ \ | |
+ _CB_res = _CB_res * 37 + *_CB_p; \ | |
+ } \ | |
+ (CB_res) = _CB_res & INT_MAX; \ | |
} while(FALSE) | |
/* get the second hash value */ | |
-#define CB_SECONDHASH(CB_res, CB_kbuf, CB_ksiz) \ | |
- do { \ | |
- const unsigned char *_CB_p; \ | |
- int _CB_ksiz; \ | |
- _CB_p = (const unsigned char *)(CB_kbuf) + CB_ksiz - 1; \ | |
- _CB_ksiz = CB_ksiz; \ | |
- for((CB_res) = 0x13579bdf; _CB_ksiz--;){ \ | |
- (CB_res) = (CB_res) * 31 + *(_CB_p)--; \ | |
- } \ | |
- (CB_res) &= INT_MAX; \ | |
+#define CB_SECONDHASH(CB_res, CB_kbuf, CB_ksiz) \ | |
+ do { \ | |
+ const unsigned char *_CB_p = \ | |
+ (const unsigned char *)(CB_kbuf) + (CB_ksiz) - 1; \ | |
+ int _CB_ksiz = (CB_ksiz); \ | |
+ unsigned int _CB_res; \ | |
+ for(_CB_res = 0x13579bdf; _CB_ksiz--; _CB_p--){ \ | |
+ _CB_res = _CB_res * 31 + *_CB_p; \ | |
+ } \ | |
+ (CB_res) = _CB_res & INT_MAX; \ | |
} while(FALSE) | |
diff --git a/depot.c b/depot.c | |
index 717335b..b25ae23 100644 | |
--- a/depot.c | |
+++ b/depot.c | |
@@ -41,45 +41,45 @@ | |
#define DP_IOBUFSIZ 8192 /* size of an I/O buffer */ | |
/* get the first hash value */ | |
-#define DP_FIRSTHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
- do { \ | |
- const unsigned char *_DP_p; \ | |
- int _DP_ksiz; \ | |
- _DP_p = (const unsigned char *)(DP_kbuf); \ | |
- _DP_ksiz = DP_ksiz; \ | |
- if((_DP_ksiz) == sizeof(int)){ \ | |
- memcpy(&(DP_res), (DP_kbuf), sizeof(int)); \ | |
- } else { \ | |
- (DP_res) = 751; \ | |
- } \ | |
- while(_DP_ksiz--){ \ | |
- (DP_res) = (DP_res) * 31 + *(_DP_p)++; \ | |
- } \ | |
- (DP_res) = ((DP_res) * 87767623) & INT_MAX; \ | |
+#define DP_FIRSTHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
+ do { \ | |
+ const unsigned char *_DP_p = (const unsigned char *)(DP_kbuf); \ | |
+ int _DP_ksiz = (DP_ksiz); \ | |
+ unsigned int _DP_res; \ | |
+ if((_DP_ksiz) == sizeof(int)){ \ | |
+ memcpy(&_DP_res, _DP_p, sizeof(int)); \ | |
+ } else { \ | |
+ _DP_res = 751; \ | |
+ } \ | |
+ while(_DP_ksiz--){ \ | |
+ _DP_res = _DP_res * 31 + *_DP_p; \ | |
+ _DP_p++; \ | |
+ } \ | |
+ (DP_res) = (_DP_res * 87767623) & INT_MAX; \ | |
} while(FALSE) | |
/* get the second hash value */ | |
-#define DP_SECONDHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
- do { \ | |
- const unsigned char *_DP_p; \ | |
- int _DP_ksiz; \ | |
- _DP_p = (const unsigned char *)(DP_kbuf) + DP_ksiz - 1; \ | |
- _DP_ksiz = DP_ksiz; \ | |
- for((DP_res) = 19780211; _DP_ksiz--;){ \ | |
- (DP_res) = (DP_res) * 37 + *(_DP_p)--; \ | |
- } \ | |
- (DP_res) = ((DP_res) * 43321879) & INT_MAX; \ | |
+#define DP_SECONDHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
+ do { \ | |
+ const unsigned char *_DP_p = \ | |
+ (const unsigned char *)(DP_kbuf) + (DP_ksiz) - 1; \ | |
+ int _DP_ksiz = (DP_ksiz); \ | |
+ unsigned int _DP_res; \ | |
+ for(_DP_res = 19780211; _DP_ksiz--; _DP_p--){ \ | |
+ _DP_res = _DP_res * 37 + *_DP_p; \ | |
+ } \ | |
+ (DP_res) = (_DP_res * 43321879) & INT_MAX; \ | |
} while(FALSE) | |
/* get the third hash value */ | |
-#define DP_THIRDHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
- do { \ | |
- int _DP_i; \ | |
- (DP_res) = 774831917; \ | |
- for(_DP_i = (DP_ksiz) - 1; _DP_i >= 0; _DP_i--){ \ | |
- (DP_res) = (DP_res) * 29 + ((const unsigned char *)(DP_kbuf))[_DP_i]; \ | |
- } \ | |
- (DP_res) = ((DP_res) * 5157883) & INT_MAX; \ | |
+#define DP_THIRDHASH(DP_res, DP_kbuf, DP_ksiz) \ | |
+ do { \ | |
+ int _DP_i; \ | |
+ unsigned int _DP_res = 774831917; \ | |
+ for(_DP_i = (DP_ksiz) - 1; _DP_i >= 0; _DP_i--){ \ | |
+ _DP_res = _DP_res * 29 + ((const unsigned char *)(DP_kbuf))[_DP_i]; \ | |
+ } \ | |
+ (DP_res) = (_DP_res * 5157883) & INT_MAX; \ | |
} while(FALSE) | |
enum { /* enumeration for a record header */ | |
-- | |
2.32.0 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 644f386143939ee8f20dd444d1aa707ea2a3033b Mon Sep 17 00:00:00 2001 | |
From: Kazuhiro Ito <[email protected]> | |
Date: Tue, 27 Jul 2021 19:40:48 +0900 | |
Subject: [PATCH 2/4] Fix dpget() may return wrong *sp value | |
--- | |
depot.c | 17 +++++++++++------ | |
1 file changed, 11 insertions(+), 6 deletions(-) | |
diff --git a/depot.c b/depot.c | |
index b25ae23..711013c 100644 | |
--- a/depot.c | |
+++ b/depot.c | |
@@ -114,7 +114,7 @@ static int dppadsize(DEPOT *depot, int ksiz, int vsiz); | |
static int dprecsize(int *head); | |
static int dprechead(DEPOT *depot, int off, int *head, char *ebuf, int *eep); | |
static char *dpreckey(DEPOT *depot, int off, int *head); | |
-static char *dprecval(DEPOT *depot, int off, int *head, int start, int max); | |
+static char *dprecval(DEPOT *depot, int off, int *head, int start, int max, int *sp); | |
static int dprecvalwb(DEPOT *depot, int off, int *head, int start, int max, char *vbuf); | |
static int dpkeycmp(const char *abuf, int asiz, const char *bbuf, int bsiz); | |
static int dprecsearch(DEPOT *depot, const char *kbuf, int ksiz, int hash, int *bip, int *offp, | |
@@ -413,7 +413,7 @@ int dpput(DEPOT *depot, const char *kbuf, int ksiz, const char *vbuf, int vsiz, | |
} | |
memcpy(tval, ebuf + (DP_RHNUM * sizeof(int) + head[DP_RHIKSIZ]), head[DP_RHIVSIZ]); | |
} else { | |
- if(!(tval = dprecval(depot, off, head, 0, -1))){ | |
+ if(!(tval = dprecval(depot, off, head, 0, -1, NULL))){ | |
depot->fatal = TRUE; | |
return FALSE; | |
} | |
@@ -568,7 +568,7 @@ char *dpget(DEPOT *depot, const char *kbuf, int ksiz, int start, int max, int *s | |
memcpy(vbuf, ebuf + (DP_RHNUM * sizeof(int) + head[DP_RHIKSIZ] + start), vsiz); | |
vbuf[vsiz] = '\0'; | |
} else { | |
- if(!(vbuf = dprecval(depot, off, head, start, max))){ | |
+ if(!(vbuf = dprecval(depot, off, head, start, max, &vsiz))){ | |
depot->fatal = TRUE; | |
return NULL; | |
} | |
@@ -837,11 +837,11 @@ int dpoptimize(DEPOT *depot, int bnum){ | |
memcpy(vbufs[unum], ebuf + (DP_RHNUM * sizeof(int) + head[DP_RHIKSIZ]), | |
head[DP_RHIVSIZ]); | |
} else { | |
- vbufs[unum] = dprecval(depot, off, head, 0, -1); | |
+ vbufs[unum] = dprecval(depot, off, head, 0, -1, NULL); | |
} | |
} else { | |
kbufs[unum] = dpreckey(depot, off, head); | |
- vbufs[unum] = dprecval(depot, off, head, 0, -1); | |
+ vbufs[unum] = dprecval(depot, off, head, 0, -1, NULL); | |
} | |
ksizs[unum] = head[DP_RHIKSIZ]; | |
vsizs[unum] = head[DP_RHIVSIZ]; | |
@@ -1851,8 +1851,9 @@ static char *dpreckey(DEPOT *depot, int off, int *head){ | |
`head' specifies the header of a record. | |
`start' specifies the offset address of the beginning of the region of the value to be read. | |
`max' specifies the max size to be read. If it is negative, the size to read is unlimited. | |
+ `sp' specifies the pointer to return the size of the netity. | |
The return value is a value data whose region is allocated by `malloc', or NULL on failure. */ | |
-static char *dprecval(DEPOT *depot, int off, int *head, int start, int max){ | |
+static char *dprecval(DEPOT *depot, int off, int *head, int start, int max, int *sp){ | |
char *vbuf; | |
int vsiz; | |
assert(depot && off >= 0 && start >= 0); | |
@@ -1872,6 +1873,10 @@ static char *dprecval(DEPOT *depot, int off, int *head, int start, int max){ | |
} | |
vbuf[vsiz] = '\0'; | |
return vbuf; | |
+ | |
+ if (sp){ | |
+ *sp = vsiz; | |
+ } | |
} | |
-- | |
2.32.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment