Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ikazuhiro/4e94018c007fb21cf2b9b14e9b0bc97a to your computer and use it in GitHub Desktop.
Save ikazuhiro/4e94018c007fb21cf2b9b14e9b0bc97a to your computer and use it in GitHub Desktop.
QDBM 1.8.78 bug fix
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
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