Random observations of a very experienced software artist.

    How not to perform a Select Case

    John McCann  September 20 2012 05:30:18 PM
    This is a LotusScript example of how NOT to code Select Case.   I found this in an application I had to change.

    The code was in a function that tries to find the proper document  in the Domino Directory based on having a full name, an email address, and/or the name from the x.509 certificate.  The routine takes a parameter on how to search:
    ' Parms:    rintType ......... flag that indicates what type of search to do
    '                    ......... 1 = Attempt to match on NameFull        
    '                    ......... 2 = Attempt to match on EMail
    '                    ......... 3 = Attempt to match on EMail Address if NameFull fails
    '                    ......... 4 = Attempt to match on PKI Name
    '                    ......... 5 = Attempt to match on PKI Name if NameFull and EMail fail

    Note that types 3 and 5 instruct the routine to use multiple methods until success is achieved.  The code was basically this:

     ' view we need Domino Directory
            Set vwNAB = dbNAB.GetView("($Users)")
    ' Assume NOT found
            rintFound = 0
    ' Processing depends on Request Type
            Select Case rintType
            Case Is = 1, 3, 5
                    '.. see if we can match on FullName
                    Set docPerson = vwNAB.GetDocumentByKey(rstrFullName, True)
                    If Not (docPerson Is Nothing) Then
                            rintFound = 1
                    End If
            Case Is = 2, 3, 5        
                    '.. if no match already or Email only .. see if we can match on EMail Address
                    If rintFound = 0 Then                  
                            If rstrEMail <> "" Then
                                    If vwNAB.FTSearch(rstrEMail) > 0 Then
                                            Set docPerson = vwNAB.GetFirstDocument()
                                            rintFound = 2
                                    End If
                            End If
                    End If
            Case Is = 4, 5                
                    '.. see if we can match on PKI Name
                    If rintFound = 0 Then                  
                            If rstrNamePKI <> "" Then
                                    Set docPerson = vwNAB.GetDocumentByKey(rstrPKIName, True)
                                    If Not (docPerson Is Nothing) Then
                                            rintFound = 3
                                    End If
                            End If
                    End If                
            End Select

    Select case only takes a single "Case".  If rintType is 3 or 5, the 2nd and 3rd Cases never get chosen, only the first.   The routine fails to find the person document, even when there is a match on email or PKI name.   I can only guess that the original hacker thought Select Case evaluated each case in turn.

    By the way, there was another gotcha here.  The variable for the view, vwNAB, is established outside the routine that actually contains this code.  The routine fails if multiple techniques were used to call the function in a single execution of an agent, say Type=2 followed by Type=1.  The FTSearch is never cleared and any non-FTSearch based lookup into the view probably fails.  

    Yes, I did rewrite this routine.

    Lesson for the day: Select Case executes at most ONE case.


    1Nathan T Freeman  9/20/2012 8:49:56 PM  How not to perform a Select Case

    Its possible that the person that wrote it had a Java background, where Switch statements fall through to subsequent cases even if one already matched. This guess would be supported by the fact that they used an integer instead of a string for the cases.

    This type of switch might also be standard in C or other languages. I just know for sure that its like this in Java.

    2Mark Chapa  9/21/2012 11:23:06 AM  How not to perform a Select Case

    Case can evaluate multiple conditions. I've used multiple conditions before but not with the Is operator.

    You can have

    select case x

    Case 3,4,5

    code to execute...

    and when x is 3 or 4 or 5, "code to execute" will run.

    Strings will also work:

    case "A", "D", "F"

    code to execute...

    case else

    when A or D or F, code to execute will run