digitalmars.D.learn - incorrect data when returning static array in place of dynamic
- sigod (40/40) Jul 05 2015 Consider this code:
- thedeemon (7/10) Jul 05 2015 Because sha1Of() returns ubyte[20], this is a stack-allocated
- sigod (14/24) Jul 06 2015 Aren't compiler smart enough to prevent it?
- anonymous (3/16) Jul 06 2015 dmd 2.068.0 catches this. You can get the beta here:
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (2/4) Jul 06 2015 ... and it already contains a std.digest.hmac module :-)
- sigod (3/7) Jul 10 2015 Yes, thanks. I know that. But I don't really want to use
- sigod (2/22) Jul 10 2015 That's good to know.
Consider this code: ``` import std.digest.digest; import std.stdio; ubyte[] hmac_sha1(const(ubyte)[] key, const(ubyte)[] message) { import std.digest.sha; enum block_size = 64; if (key.length > block_size) key = sha1Of(key); if (key.length < block_size) key.length = block_size; ubyte[] o_key_pad = key.dup; ubyte[] i_key_pad = key.dup; o_key_pad[] ^= 0x5c; i_key_pad[] ^= 0x36; sha1Of(o_key_pad ~ sha1Of(i_key_pad ~ message)).toHexString.writeln; // prints correct string return sha1Of(o_key_pad ~ sha1Of(i_key_pad ~ message)); } void main() { hmac_sha1(cast(ubyte[])"", cast(ubyte[])"").toHexString.writeln; // incorrect "---".writeln; hmac_sha1(cast(ubyte[])"key", cast(ubyte[])"The quick brown fox jumps over the lazy dog").toHexString.writeln; } ``` prints: ``` FBDB1D1B18AA6C08324B7D64B71FB76370690E1D 0000000018AA6C081400000038FD180010000000 --- DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9 00000000B8B78AA61400000038FD180010000000 ``` Why does function return incorrect data? Using `.dup` in return expression or using `ubyte[20]` as return type fixes problem, but why?
Jul 05 2015
On Sunday, 5 July 2015 at 18:57:46 UTC, sigod wrote:Why does function return incorrect data? Using `.dup` in return expression or using `ubyte[20]` as return type fixes problem, but why?Because sha1Of() returns ubyte[20], this is a stack-allocated array, a value type. If you put correct return type there, it will be returned by value and everything's fine. If your return type is ubyte[] (a reference type), a slice of stack-allocated array is returned which creates a reference to stack data that doesn't exist anymore.
Jul 05 2015
On Monday, 6 July 2015 at 05:30:46 UTC, thedeemon wrote:On Sunday, 5 July 2015 at 18:57:46 UTC, sigod wrote:Aren't compiler smart enough to prevent it? ``` ubyte[] test1() { auto b = sha1Of(""); return b; // Error: escaping reference to local b } ubyte[] test2() { return sha1Of(""); // works, but returns incorrect data } ``` Looks more like a bug to me.Why does function return incorrect data? Using `.dup` in return expression or using `ubyte[20]` as return type fixes problem, but why?Because sha1Of() returns ubyte[20], this is a stack-allocated array, a value type. If you put correct return type there, it will be returned by value and everything's fine. If your return type is ubyte[] (a reference type), a slice of stack-allocated array is returned which creates a reference to stack data that doesn't exist anymore.
Jul 06 2015
On Monday, 6 July 2015 at 07:48:17 UTC, sigod wrote:Aren't compiler smart enough to prevent it? ``` ubyte[] test1() { auto b = sha1Of(""); return b; // Error: escaping reference to local b } ubyte[] test2() { return sha1Of(""); // works, but returns incorrect data } ``` Looks more like a bug to me.dmd 2.068.0 catches this. You can get the beta here: http://downloads.dlang.org/pre-releases/2.x/2.068.0/
Jul 06 2015
On Monday, 6 July 2015 at 10:20:28 UTC, anonymous wrote:dmd 2.068.0 catches this. You can get the beta here: http://downloads.dlang.org/pre-releases/2.x/2.068.0/... and it already contains a std.digest.hmac module :-)
Jul 06 2015
On Monday, 6 July 2015 at 14:56:38 UTC, Marc Schütz wrote:On Monday, 6 July 2015 at 10:20:28 UTC, anonymous wrote:Yes, thanks. I know that. But I don't really want to use pre-release version on server.dmd 2.068.0 catches this. You can get the beta here: http://downloads.dlang.org/pre-releases/2.x/2.068.0/... and it already contains a std.digest.hmac module :-)
Jul 10 2015
On Monday, 6 July 2015 at 10:20:28 UTC, anonymous wrote:On Monday, 6 July 2015 at 07:48:17 UTC, sigod wrote:That's good to know.Aren't compiler smart enough to prevent it? ``` ubyte[] test1() { auto b = sha1Of(""); return b; // Error: escaping reference to local b } ubyte[] test2() { return sha1Of(""); // works, but returns incorrect data } ``` Looks more like a bug to me.dmd 2.068.0 catches this. You can get the beta here: http://downloads.dlang.org/pre-releases/2.x/2.068.0/
Jul 10 2015