diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-23 08:35:34 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-05-23 08:35:34 +0000 |
commit | f8180b8963a693d92a2be906a06ef2ffc204c284 (patch) | |
tree | dd8ee4739df70f7868019b51c4e318dd648b578b /load.c | |
parent | 699e06a88421cf325f8d191dc8582ab8cb7aa92f (diff) | |
download | ruby-f8180b8963a693d92a2be906a06ef2ffc204c284.tar.gz |
load.c: fix invalid read
* load.c (loaded_feature_path): fix invalid read by index underflow.
the beginning of name is also a boundary as well as just after '/'.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40900 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'load.c')
-rw-r--r-- | load.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -315,7 +315,7 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len, if (vlen < len+1) return 0; if (!strncmp(name+(vlen-len), feature, len)) { - plen = vlen - len - 1; + plen = vlen - len; } else { for (e = name + vlen; name != e && *e != '.' && *e != '/'; --e); @@ -323,19 +323,20 @@ loaded_feature_path(const char *name, long vlen, const char *feature, long len, e-name < len || strncmp(e-len, feature, len)) return 0; - plen = e - name - len - 1; + plen = e - name - len; } - if (name[plen] != '/') { + if (plen > 0 && name[plen-1] != '/') { return 0; } - if (type == 's' ? !IS_DLEXT(&name[plen+len+1]) : - type == 'r' ? !IS_RBEXT(&name[plen+len+1]) : + if (type == 's' ? !IS_DLEXT(&name[plen+len]) : + type == 'r' ? !IS_RBEXT(&name[plen+len]) : 0) { return 0; } /* Now name == "#{prefix}/#{feature}#{ext}" where ext is acceptable (possibly empty) and prefix is some string of length plen. */ + if (plen > 0) --plen; /* exclude '.' */ for (i = 0; i < RARRAY_LEN(load_path); ++i) { VALUE p = RARRAY_AREF(load_path, i); const char *s = StringValuePtr(p); |