1

The problem is in the middle of Main at the line that reads

if ((byte[])Dts.Variables["User::EncryptionKey"].Value == noKey)

When GetEncryptionKey 'fails' and returns noKey, the 'if' still takes the 'else' path and I don't see why. I tried this with identical results.

if (noKey.Equals((byte[])Dts.Variables["User::EncryptionKey"].Value))

Unless every reference to noKey is somehow instantiating a new copy of byte[0] I don't see how they can be unequal. I've stepped thru numerous times and they certainly look equal.

    private static byte[] noKey = new byte[0];

    public void Main()
    {
        int keyLen = 32;
            Dts.Variables["User::EncryptionKey"].Value =
                GetEncryptionKey((string)Dts.Variables["User::EncryptionKeyAsHex"].Value, keyLen);

        if ((byte[])Dts.Variables["User::EncryptionKey"].Value == noKey)
        {
            Dts.TaskResult = (int)ScriptResults.Failure;
        }
        else
        {
            Dts.TaskResult = (int)ScriptResults.Success;
        }
    }

    private static byte[] GetEncryptionKey(string hexString,int numBytes)
    {
            return noKey;  //<-this definitely does get hit!
    }
bielawski
  • 1,466
  • 15
  • 20
  • 4
    Well, you're performing a reference comparison. If assigning to the `Value` property (or fetching it) takes a copy of the array, that would explain things... can you reduce this to a [mcve]? (There's a lot of code here, most of which looks like it's unnecessary to reproduce this...) – Jon Skeet May 25 '17 at 18:46
  • 2
    Possible duplicate of [Checking equality for two byte arrays](https://stackoverflow.com/questions/18472867/checking-equality-for-two-byte-arrays) – Eris May 25 '17 at 18:49
  • Looks like you're tripping on autoboxing. See "[Compare two arrays of primitives in Java?](https://stackoverflow.com/questions/630808/compare-two-arrays-of-primitives-in-java)". – Jim Scarborough May 25 '17 at 18:50
  • 1
    Please provide [MCVE]. Currently there is no clear correlation between `(byte[])Dts.Variables["User::EncryptionKey"].Value == noKey` and " GetEncryptionKey 'fails' and returns noKey" – Alexei Levenkov May 25 '17 at 18:57
  • I've minimalized the code. Unfortunately, this being SSIS Script-Task code I don't know anything about the implementation of Dts.Variables[x].Value other than it's presented to me as type object. – bielawski May 25 '17 at 19:09
  • 1
    @bielawski `private static byte[] noKey = new byte[] { 255 };`. After putting it in `Dts.Variables`, set `noKey[0] = 254`. Grab the value back from `Dts.Variables` stick it in a local `a`, and look at `a[0]`. If it's 254, it's the same array. If it's 255, the swine snuck in a copy on you, heaven knows how or why. In that case, convert a Guid to an array for your magic value, or just cast to `byte[]` and check for `Length == 0`, unless a valid key can have a length of zero. Or does it even *have* to be a byte array? The thing is storing `object`, right? – 15ee8f99-57ff-4f92-890c-b56153 May 25 '17 at 19:14
  • Is the Dts variable marked as ReadOnly? – JuanR May 25 '17 at 19:23
  • It would be great if you can post the Watch List output for noKey and Dts.Variables["User::EncryptionKey"].Value, but being it's an ecryption key, I doubt you would share that. Take a look in the Watch List and see what each has as a value. – JuanR May 25 '17 at 19:24
  • @ed-plunkett is onto something. The Dts value didn't change after noKey[0] did. At first it made no sense but I'm now theorizing that Value.set needs to copy the object out of the environment created for the script-task because the whole environment, including it's heap, gets disposed. – bielawski May 25 '17 at 19:52
  • 1
    @bielawski Do you even need to compare `noKey` outside of `Main()`? What I see in your original question could be rewritten so the key is in a local in `Main()`, and you compare that with `noKey`, instead of grabbing it back out of `Dts` to compare. – 15ee8f99-57ff-4f92-890c-b56153 May 25 '17 at 19:57
  • Yes, well, now that I know that I need to that is the solution. But I was certainly confused before I was prompted to consider that SSIS was going thru all the trouble it takes to copy arbitrary objects. – bielawski May 25 '17 at 20:29

2 Answers2

1

Here is where the problem lay: "Unless every reference to noKey is somehow instantiating a new copy of byte[0] I don't see how they can be unequal." It never occurred to me that Dts....Value.set was the one creating a new copy.

So thanks to Ed Plunkett for suggesting I look into that because it turned out to be true.

Storing the returned value in a local variable for use in the comparison avoids the problem.

bielawski
  • 1,466
  • 15
  • 20
0

I think you are confusing the concept here, two array are not the same because they share the same elements on it. The operator == calls the ReferenceEquals, and it checks if both elements are pointing to the same space on the memory.

Take a look on the difference here C# .Equals(), .ReferenceEquals() and == operator

Try to use the @Eris approach. Hope this help

Zinov
  • 3,817
  • 5
  • 36
  • 70