mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/dbm/dbm.c (fdbm_fetch, fdbm_key, fdbm_delete, fdbm_store)
(fdbm_has_key, fdbm_has_value): get rid of overflow. * ext/gdbm/gdbm.c (rb_gdbm_fetch2, rb_gdbm_nextkey) (rb_gdbm_delete, fgdbm_store, fgdbm_has_key): ditto. * ext/dbm/dbm.c (fdbm_delete_if): hide intermediate objects. * ext/gdbm/gdbm.c (fgdbm_delete_if): ditto. * ext/dbm/extconf.rb: check size of datum.dsize to get rid of overflow. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33676 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4342469e8c
commit
0e4c2ce841
4 changed files with 95 additions and 24 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
Tue Nov 8 23:34:37 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/dbm/dbm.c (fdbm_fetch, fdbm_key, fdbm_delete, fdbm_store)
|
||||||
|
(fdbm_has_key, fdbm_has_value): get rid of overflow.
|
||||||
|
|
||||||
|
* ext/gdbm/gdbm.c (rb_gdbm_fetch2, rb_gdbm_nextkey)
|
||||||
|
(rb_gdbm_delete, fgdbm_store, fgdbm_has_key): ditto.
|
||||||
|
|
||||||
|
* ext/dbm/dbm.c (fdbm_delete_if): hide intermediate objects.
|
||||||
|
|
||||||
|
* ext/gdbm/gdbm.c (fgdbm_delete_if): ditto.
|
||||||
|
|
||||||
|
* ext/dbm/extconf.rb: check size of datum.dsize to get rid of
|
||||||
|
overflow.
|
||||||
|
|
||||||
Tue Nov 8 23:30:21 2011 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue Nov 8 23:30:21 2011 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* addr2line.c (PATH_MAX): define if not defined. [ruby-core:40840]
|
* addr2line.c (PATH_MAX): define if not defined. [ruby-core:40840]
|
||||||
|
|
|
@ -21,6 +21,16 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if SIZEOF_DSIZE > SIZEOF_INT
|
||||||
|
# define DSIZE_TYPE long
|
||||||
|
# define RSTRING_DSIZE(s) RSTRING_LEN(s)
|
||||||
|
# define TOO_LONG(n) 0
|
||||||
|
#else
|
||||||
|
# define DSIZE_TYPE int
|
||||||
|
# define RSTRING_DSIZE(s) RSTRING_LENINT(s)
|
||||||
|
# define TOO_LONG(n) ((long)(+(DSIZE_TYPE)(n)) != (n))
|
||||||
|
#endif
|
||||||
|
|
||||||
static VALUE rb_cDBM, rb_eDBMError;
|
static VALUE rb_cDBM, rb_eDBMError;
|
||||||
|
|
||||||
#define RUBY_DBM_RW_BIT 0x20000000
|
#define RUBY_DBM_RW_BIT 0x20000000
|
||||||
|
@ -230,14 +240,18 @@ fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone)
|
||||||
datum key, value;
|
datum key, value;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
ExportStringValue(keystr);
|
ExportStringValue(keystr);
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) goto not_found;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (DSIZE_TYPE)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
value = dbm_fetch(dbm, key);
|
value = dbm_fetch(dbm, key);
|
||||||
if (value.dptr == 0) {
|
if (value.dptr == 0) {
|
||||||
|
not_found:
|
||||||
if (ifnone == Qnil && rb_block_given_p())
|
if (ifnone == Qnil && rb_block_given_p())
|
||||||
return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
|
return rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
|
||||||
return ifnone;
|
return ifnone;
|
||||||
|
@ -291,15 +305,18 @@ fdbm_key(VALUE obj, VALUE valstr)
|
||||||
datum key, val;
|
datum key, val;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
ExportStringValue(valstr);
|
ExportStringValue(valstr);
|
||||||
|
len = RSTRING_LEN(valstr);
|
||||||
|
if (TOO_LONG(len)) return Qnil;
|
||||||
val.dptr = RSTRING_PTR(valstr);
|
val.dptr = RSTRING_PTR(valstr);
|
||||||
val.dsize = (int)RSTRING_LEN(valstr);
|
val.dsize = (DSIZE_TYPE)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
||||||
val = dbm_fetch(dbm, key);
|
val = dbm_fetch(dbm, key);
|
||||||
if ((long)val.dsize == (int)RSTRING_LEN(valstr) &&
|
if ((long)val.dsize == RSTRING_LEN(valstr) &&
|
||||||
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
|
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0) {
|
||||||
return rb_tainted_str_new(key.dptr, key.dsize);
|
return rb_tainted_str_new(key.dptr, key.dsize);
|
||||||
}
|
}
|
||||||
|
@ -385,16 +402,20 @@ fdbm_delete(VALUE obj, VALUE keystr)
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
VALUE valstr;
|
VALUE valstr;
|
||||||
|
long len;
|
||||||
|
|
||||||
fdbm_modify(obj);
|
fdbm_modify(obj);
|
||||||
ExportStringValue(keystr);
|
ExportStringValue(keystr);
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) goto not_found;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (DSIZE_TYPE)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
|
|
||||||
value = dbm_fetch(dbm, key);
|
value = dbm_fetch(dbm, key);
|
||||||
if (value.dptr == 0) {
|
if (value.dptr == 0) {
|
||||||
|
not_found:
|
||||||
if (rb_block_given_p()) return rb_yield(keystr);
|
if (rb_block_given_p()) return rb_yield(keystr);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -457,7 +478,7 @@ fdbm_delete_if(VALUE obj)
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
VALUE keystr, valstr;
|
VALUE keystr, valstr;
|
||||||
VALUE ret, ary = rb_ary_new();
|
VALUE ret, ary = rb_ary_tmp_new(0);
|
||||||
int i, status = 0;
|
int i, status = 0;
|
||||||
long n;
|
long n;
|
||||||
|
|
||||||
|
@ -469,6 +490,7 @@ fdbm_delete_if(VALUE obj)
|
||||||
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
||||||
val = dbm_fetch(dbm, key);
|
val = dbm_fetch(dbm, key);
|
||||||
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
keystr = rb_tainted_str_new(key.dptr, key.dsize);
|
||||||
|
OBJ_FREEZE(keystr);
|
||||||
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
valstr = rb_tainted_str_new(val.dptr, val.dsize);
|
||||||
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
||||||
if (status != 0) break;
|
if (status != 0) break;
|
||||||
|
@ -478,15 +500,15 @@ fdbm_delete_if(VALUE obj)
|
||||||
|
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||||
keystr = RARRAY_PTR(ary)[i];
|
keystr = RARRAY_PTR(ary)[i];
|
||||||
ExportStringValue(keystr);
|
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (DSIZE_TYPE)RSTRING_LEN(keystr);
|
||||||
if (dbm_delete(dbm, key)) {
|
if (dbm_delete(dbm, key)) {
|
||||||
rb_raise(rb_eDBMError, "dbm_delete failed");
|
rb_raise(rb_eDBMError, "dbm_delete failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status) rb_jump_tag(status);
|
if (status) rb_jump_tag(status);
|
||||||
if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
|
if (n > 0) dbmp->di_size = n - RARRAY_LEN(ary);
|
||||||
|
rb_ary_clear(ary);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -607,10 +629,10 @@ fdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
|
||||||
valstr = rb_obj_as_string(valstr);
|
valstr = rb_obj_as_string(valstr);
|
||||||
|
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = RSTRING_DSIZE(keystr);
|
||||||
|
|
||||||
val.dptr = RSTRING_PTR(valstr);
|
val.dptr = RSTRING_PTR(valstr);
|
||||||
val.dsize = (int)RSTRING_LEN(valstr);
|
val.dsize = RSTRING_DSIZE(valstr);
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
dbmp->di_size = -1;
|
dbmp->di_size = -1;
|
||||||
|
@ -816,10 +838,13 @@ fdbm_has_key(VALUE obj, VALUE keystr)
|
||||||
datum key, val;
|
datum key, val;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
ExportStringValue(keystr);
|
ExportStringValue(keystr);
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) return Qfalse;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (DSIZE_TYPE)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
val = dbm_fetch(dbm, key);
|
val = dbm_fetch(dbm, key);
|
||||||
|
@ -840,15 +865,18 @@ fdbm_has_value(VALUE obj, VALUE valstr)
|
||||||
datum key, val;
|
datum key, val;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
DBM *dbm;
|
DBM *dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
ExportStringValue(valstr);
|
ExportStringValue(valstr);
|
||||||
|
len = RSTRING_LEN(valstr);
|
||||||
|
if (TOO_LONG(len)) return Qfalse;
|
||||||
val.dptr = RSTRING_PTR(valstr);
|
val.dptr = RSTRING_PTR(valstr);
|
||||||
val.dsize = (int)RSTRING_LEN(valstr);
|
val.dsize = (DSIZE_TYPE)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
|
||||||
val = dbm_fetch(dbm, key);
|
val = dbm_fetch(dbm, key);
|
||||||
if (val.dsize == (int)RSTRING_LEN(valstr) &&
|
if ((DSIZE_TYPE)val.dsize == (DSIZE_TYPE)RSTRING_LEN(valstr) &&
|
||||||
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
memcmp(val.dptr, RSTRING_PTR(valstr), val.dsize) == 0)
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,10 @@ headers = {
|
||||||
"qdbm" => ["relic.h", "qdbm/relic.h"],
|
"qdbm" => ["relic.h", "qdbm/relic.h"],
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbm_headers = []
|
class << headers
|
||||||
|
attr_accessor :found
|
||||||
|
end
|
||||||
|
headers.found = []
|
||||||
|
|
||||||
def headers.db_check(db)
|
def headers.db_check(db)
|
||||||
db_prefix = nil
|
db_prefix = nil
|
||||||
|
@ -46,7 +49,7 @@ def headers.db_check(db)
|
||||||
have_func(db_prefix+"dbm_clearerr") unless have_gdbm
|
have_func(db_prefix+"dbm_clearerr") unless have_gdbm
|
||||||
$defs << hsearch if hsearch
|
$defs << hsearch if hsearch
|
||||||
$defs << '-DDBM_HDR="<'+hdr+'>"'
|
$defs << '-DDBM_HDR="<'+hdr+'>"'
|
||||||
$dbm_headers << hdr
|
@found << hdr
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
false
|
false
|
||||||
|
@ -56,7 +59,12 @@ end
|
||||||
if dblib.any? {|db| headers.db_check(db)}
|
if dblib.any? {|db| headers.db_check(db)}
|
||||||
have_header("cdefs.h")
|
have_header("cdefs.h")
|
||||||
have_header("sys/cdefs.h")
|
have_header("sys/cdefs.h")
|
||||||
have_func("dbm_pagfno", $dbm_headers)
|
have_func("dbm_pagfno", headers.found)
|
||||||
have_func("dbm_dirfno", $dbm_headers)
|
have_func("dbm_dirfno", headers.found)
|
||||||
|
if try_static_assert("sizeof(conftest_key.dsize) <= sizeof(int)", [[cpp_include(headers.found), "static datum conftest_key;"]])
|
||||||
|
$defs << "-DSIZEOF_DSIZE=SIZEOF_INT"
|
||||||
|
else
|
||||||
|
$defs << "-DSIZEOF_DSIZE=SIZEOF_LONG"
|
||||||
|
end
|
||||||
create_makefile("dbm")
|
create_makefile("dbm")
|
||||||
end
|
end
|
||||||
|
|
|
@ -73,6 +73,12 @@
|
||||||
*/
|
*/
|
||||||
static VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;
|
static VALUE rb_cGDBM, rb_eGDBMError, rb_eGDBMFatalError;
|
||||||
|
|
||||||
|
#if SIZEOF_LONG > SIZEOF_INT
|
||||||
|
#define TOO_LONG(n) ((long)(+(int)(n)) != (long)(n))
|
||||||
|
#else
|
||||||
|
#define TOO_LONG(n) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RUBY_GDBM_RW_BIT 0x20000000
|
#define RUBY_GDBM_RW_BIT 0x20000000
|
||||||
|
|
||||||
#define MY_BLOCK_SIZE (2048)
|
#define MY_BLOCK_SIZE (2048)
|
||||||
|
@ -301,10 +307,13 @@ static VALUE
|
||||||
rb_gdbm_fetch2(GDBM_FILE dbm, VALUE keystr)
|
rb_gdbm_fetch2(GDBM_FILE dbm, VALUE keystr)
|
||||||
{
|
{
|
||||||
datum key;
|
datum key;
|
||||||
|
long len;
|
||||||
|
|
||||||
StringValue(keystr);
|
StringValue(keystr);
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) return Qnil;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (int)len;
|
||||||
|
|
||||||
return rb_gdbm_fetch(dbm, key);
|
return rb_gdbm_fetch(dbm, key);
|
||||||
}
|
}
|
||||||
|
@ -340,9 +349,12 @@ rb_gdbm_nextkey(GDBM_FILE dbm, VALUE keystr)
|
||||||
{
|
{
|
||||||
datum key, key2;
|
datum key, key2;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
long len;
|
||||||
|
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) return Qnil;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (int)len;
|
||||||
key2 = gdbm_nextkey(dbm, key);
|
key2 = gdbm_nextkey(dbm, key);
|
||||||
if (key2.dptr == 0)
|
if (key2.dptr == 0)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
@ -499,11 +511,14 @@ rb_gdbm_delete(VALUE obj, VALUE keystr)
|
||||||
datum key;
|
datum key;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
GDBM_FILE dbm;
|
GDBM_FILE dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
rb_gdbm_modify(obj);
|
rb_gdbm_modify(obj);
|
||||||
StringValue(keystr);
|
StringValue(keystr);
|
||||||
|
len = RSTRING_LEN(keystr);
|
||||||
|
if (TOO_LONG(len)) return Qnil;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (int)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
if (!gdbm_exists(dbm, key)) {
|
if (!gdbm_exists(dbm, key)) {
|
||||||
|
@ -574,7 +589,7 @@ fgdbm_delete_if(VALUE obj)
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
GDBM_FILE dbm;
|
GDBM_FILE dbm;
|
||||||
VALUE keystr, valstr;
|
VALUE keystr, valstr;
|
||||||
VALUE ret, ary = rb_ary_new();
|
VALUE ret, ary = rb_ary_tmp_new(0);
|
||||||
int i, status = 0, n;
|
int i, status = 0, n;
|
||||||
|
|
||||||
rb_gdbm_modify(obj);
|
rb_gdbm_modify(obj);
|
||||||
|
@ -585,8 +600,9 @@ fgdbm_delete_if(VALUE obj)
|
||||||
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
for (keystr = rb_gdbm_firstkey(dbm); RTEST(keystr);
|
||||||
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
keystr = rb_gdbm_nextkey(dbm, keystr)) {
|
||||||
|
|
||||||
|
OBJ_FREEZE(keystr);
|
||||||
valstr = rb_gdbm_fetch2(dbm, keystr);
|
valstr = rb_gdbm_fetch2(dbm, keystr);
|
||||||
ret = rb_protect(rb_yield, rb_assoc_new(keystr, valstr), &status);
|
ret = rb_protect(rb_yield, rb_assoc_new(rb_str_dup(keystr), valstr), &status);
|
||||||
if (status != 0) break;
|
if (status != 0) break;
|
||||||
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
if (RTEST(ret)) rb_ary_push(ary, keystr);
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
|
@ -596,6 +612,7 @@ fgdbm_delete_if(VALUE obj)
|
||||||
rb_gdbm_delete(obj, RARRAY_PTR(ary)[i]);
|
rb_gdbm_delete(obj, RARRAY_PTR(ary)[i]);
|
||||||
if (status) rb_jump_tag(status);
|
if (status) rb_jump_tag(status);
|
||||||
if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
|
if (n > 0) dbmp->di_size = n - (int)RARRAY_LEN(ary);
|
||||||
|
rb_ary_clear(ary);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -687,10 +704,10 @@ fgdbm_store(VALUE obj, VALUE keystr, VALUE valstr)
|
||||||
StringValue(valstr);
|
StringValue(valstr);
|
||||||
|
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = RSTRING_LENINT(keystr);
|
||||||
|
|
||||||
val.dptr = RSTRING_PTR(valstr);
|
val.dptr = RSTRING_PTR(valstr);
|
||||||
val.dsize = (int)RSTRING_LEN(valstr);
|
val.dsize = RSTRING_LENINT(valstr);
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
dbmp->di_size = -1;
|
dbmp->di_size = -1;
|
||||||
|
@ -943,10 +960,13 @@ fgdbm_has_key(VALUE obj, VALUE keystr)
|
||||||
datum key;
|
datum key;
|
||||||
struct dbmdata *dbmp;
|
struct dbmdata *dbmp;
|
||||||
GDBM_FILE dbm;
|
GDBM_FILE dbm;
|
||||||
|
long len;
|
||||||
|
|
||||||
StringValue(keystr);
|
StringValue(keystr);
|
||||||
|
len = RSTRING_LENINT(keystr);
|
||||||
|
if (TOO_LONG(len)) return Qfalse;
|
||||||
key.dptr = RSTRING_PTR(keystr);
|
key.dptr = RSTRING_PTR(keystr);
|
||||||
key.dsize = (int)RSTRING_LEN(keystr);
|
key.dsize = (int)len;
|
||||||
|
|
||||||
GetDBM2(obj, dbmp, dbm);
|
GetDBM2(obj, dbmp, dbm);
|
||||||
if (gdbm_exists(dbm, key))
|
if (gdbm_exists(dbm, key))
|
||||||
|
|
Loading…
Add table
Reference in a new issue