-2

I'm on an upgrade project and recently began experiencing issues with the upgraded version of a DLL. I decompiled the original dll and found the following if statement:

if (fieldConfiguration == null && Context.ContentDatabase != null)
{
    Item obj = Context.ContentDatabase.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

I then decompiled the upgraded version of the DLL and the statement was as follows:

if (fieldConfiguration == null && (Context.ContentDatabase ?? Context.Database) != null)
{
    Item obj = Context.ContentDatabase.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

I was able to step through the code by decompiling the DLLs with dotPeek and using the dotPeek symbol server functionality. I can see that the code is failing when using the upgrade DLL because Context.ContentDatabase is null. What I don't understand is how that double ternary operator is evaluated. Could someone clarify for me what's going on there? It seems as though the creators of this assembly wanted a null check for Context.ContentDatabase but may have made a mistake. Thanks for the help!

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
c-bro
  • 486
  • 2
  • 13

3 Answers3

2

Well yeah that looks like an error. The code is looking whether Context.ContentDatabase or Context.Database aren't null, and then continues to use the former, even if it was null.

The code should look like this:

var database = Context.ContentDatabase ?? Context.Database;

if (fieldConfiguration == null && database != null)
{
    Item obj = database.SelectSingleItem(
        string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
            (object) TemplateIDs.TemplateField, (object) fieldName));
}

Where it stores the database in a separate variable using the null-coalescing operator and then operates on that, if it isn't null.

So you should contact the team who provides this library and file a bug with them.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • Thanks! That's what I thought was going on based on my debugging but wanted a second opinion before raising the red flag. Looks like a learned a new operator too! – c-bro Sep 25 '17 at 18:27
  • This is in a 3rd party dll, so I assumed he doesn't have governance over it. It is possible though to compile an assembly after decompilation + modification, I've done it in the past. But that can be a dead end if you have to release the software or you violate any rights. – Csaba Toth Sep 25 '17 at 19:40
0

(Context.ContentDatabase ?? Context.Database) expressions end result is Context.ContentDatabase if Context.ContentDatabase is not null, otherwise it'll be Context.Database. The null-coalesce operator is a step forward to terse null checks.

Docs: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operator

Csaba Toth
  • 10,021
  • 5
  • 75
  • 121
0

Assuming Context.ContentDatabase and Context.Database are same types. The below code should work.

var contentDatabase = Context.ContentDatabase ?? Context.Database;
if (fieldConfiguration == null && contentDatabase != null)
{
Item obj = contentDatabase.SelectSingleItem(
    string.Format("//*[@@templateid='{0}' and @@key='{1}']", 
        (object) TemplateIDs.TemplateField, (object) fieldName));
}
Ram Pratap
  • 1,079
  • 11
  • 8
  • I don't have access to the source code in this instance but I can definitely send this along when I raise the red flag. Thanks! – c-bro Sep 25 '17 at 18:29