Skip to content

Commit 3427222

Browse files
authored
Merge pull request #824 from rhenium/ky/cipher-update-make-buffer-independent
cipher: make output buffer String independent
2 parents f9ec66f + 9cc8a83 commit 3427222

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

ext/openssl/ossl_cipher.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,10 @@ ossl_cipher_update(int argc, VALUE *argv, VALUE self)
409409
str = rb_str_new(0, out_len);
410410
} else {
411411
StringValue(str);
412-
rb_str_resize(str, out_len);
412+
if ((long)rb_str_capacity(str) >= out_len)
413+
rb_str_modify(str);
414+
else
415+
rb_str_modify_expand(str, out_len - RSTRING_LEN(str));
413416
}
414417

415418
if (!ossl_cipher_update_long(ctx, (unsigned char *)RSTRING_PTR(str), &out_len, in, in_len))

ext/openssl/ossl_digest.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ ossl_digest_finish(int argc, VALUE *argv, VALUE self)
232232
str = rb_str_new(NULL, out_len);
233233
} else {
234234
StringValue(str);
235+
rb_str_modify(str);
235236
rb_str_resize(str, out_len);
236237
}
237238

test/openssl/test_cipher.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,30 @@ def test_ctr_if_exists
134134
assert_equal pt, cipher.update(ct) << cipher.final
135135
end
136136

137+
def test_update_with_buffer
138+
cipher = OpenSSL::Cipher.new("aes-128-ecb").encrypt
139+
cipher.random_key
140+
expected = cipher.update("data") << cipher.final
141+
assert_equal 16, expected.bytesize
142+
143+
# Buffer is supplied
144+
cipher.reset
145+
buf = String.new
146+
assert_same buf, cipher.update("data", buf)
147+
assert_equal expected, buf + cipher.final
148+
149+
# Buffer is frozen
150+
cipher.reset
151+
assert_raise(FrozenError) { cipher.update("data", String.new.freeze) }
152+
153+
# Buffer is a shared string [ruby-core:120141] [Bug #20937]
154+
cipher.reset
155+
buf = "x" * 1024
156+
shared = buf[-("data".bytesize + 32)..-1]
157+
assert_same shared, cipher.update("data", shared)
158+
assert_equal expected, shared + cipher.final
159+
end
160+
137161
def test_ciphers
138162
ciphers = OpenSSL::Cipher.ciphers
139163
assert_kind_of Array, ciphers

0 commit comments

Comments
 (0)