summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-12 15:55:04 +0000
committerrhe <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-11-12 15:55:04 +0000
commit0b845a845811f4b48e5bfdaa1ba1e2fc5f50dccc (patch)
treeed1265b036070f690985fa83057df9e0f2502ec3
parent4eb345707644e2db631d3af7f455dd976391c466 (diff)
string.c: fix memory leak in String#crypt
Use ALLOCV to allocate struct crypt_data for slightly cleaner and less error-prone code. It is currently possible it leaks when an invalid argument is passed to String#crypt or rb_str_new_cstr() fails to allocate memory. SIZEOF_CRYPT_DATA macro in missing/crypt.h is removed since it is not used any longer. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60748 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--missing/crypt.h2
-rw-r--r--string.c18
2 files changed, 6 insertions, 14 deletions
diff --git a/missing/crypt.h b/missing/crypt.h
index 7a78767931..7c2642f593 100644
--- a/missing/crypt.h
+++ b/missing/crypt.h
@@ -237,8 +237,6 @@ struct crypt_data {
char cryptresult[1+4+4+11+1]; /* encrypted result */
};
-#define SIZEOF_CRYPT_DATA (KS_SIZE*8+(1+4+4+11+1))
-
char *crypt(const char *key, const char *setting);
void setkey(const char *key);
void encrypt(char *block, int flag);
diff --git a/string.c b/string.c
index 5731807379..983fa919fa 100644
--- a/string.c
+++ b/string.c
@@ -8839,14 +8839,9 @@ rb_str_oct(VALUE str)
static VALUE
rb_str_crypt(VALUE str, VALUE salt)
{
-#undef LARGE_CRYPT_DATA
#ifdef HAVE_CRYPT_R
-# if defined SIZEOF_CRYPT_DATA && SIZEOF_CRYPT_DATA <= 256
- struct crypt_data cdata, *const data = &cdata;
-# else
-# define LARGE_CRYPT_DATA
- struct crypt_data *data = ALLOC(struct crypt_data);
-# endif
+ VALUE databuf;
+ struct crypt_data *data;
#else
extern char *crypt(const char *, const char *);
#endif
@@ -8877,6 +8872,7 @@ rb_str_crypt(VALUE str, VALUE salt)
}
#endif
#ifdef HAVE_CRYPT_R
+ data = ALLOCV(databuf, sizeof(struct crypt_data));
# ifdef HAVE_STRUCT_CRYPT_DATA_INITIALIZED
data->initialized = 0;
# endif
@@ -8885,17 +8881,15 @@ rb_str_crypt(VALUE str, VALUE salt)
res = crypt(s, saltp);
#endif
if (!res) {
-#ifdef LARGE_CRYPT_DATA
+#ifdef HAVE_CRYPT_R
int err = errno;
- xfree(data);
+ ALLOCV_END(databuf);
errno = err;
#endif
rb_sys_fail("crypt");
}
result = rb_str_new_cstr(res);
-#ifdef LARGE_CRYPT_DATA
- xfree(data);
-#endif
+ ALLOCV_END(databuf);
FL_SET_RAW(result, OBJ_TAINTED_RAW(str) | OBJ_TAINTED_RAW(salt));
return result;
}