Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Wednesday, 7. July 2010


Strange bug in Dynamics NAV client

Filed under: Dynamics NAV 2009,Navision — Steffen Forkmann at 7:34 Uhr

My colleague Mathias Meissner found a strange bug in the Dynamics NAV Client (occurs at least in the native clients for NAV 403, 501 and 601). It seems the following code creates a strange memory allocation issue. (Download sample)

OBJECT Codeunit 99500 NAV Bug
{
  OBJECT-PROPERTIES
  {
    Date=17.06.10;
    Time=14:30:30;
    Modified=Yes;
    Version List=;
  }
  PROPERTIES
  {
    OnRun=BEGIN
            TestMiddleCase;  // comment this line out and ReverseString works!
            TestReverseString;
          END;

  }
  CODE
  {

    PROCEDURE TestMiddleCase@5128500();
    BEGIN
      MiddleCase('fooo AnD bar');
    END;

    PROCEDURE TestReverseString@5128502();
    VAR
      l_String@5128500 : Text[1024];
      l_Result@5128503 : Integer;
    BEGIN
      l_String :=
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011' +
        '1101101111011011110110111101101111011011110110111101101111011011';

      IF STRLEN(l_String) <> 512 THEN
        ERROR('Wrong strlen');

      l_Result := TestReverseStringSub(l_String);

      IF l_Result <> 512 THEN
        ERROR('Error: Actual: ' + FORMAT(l_Result) + ' ' + ' Expected: 512');
    END;

    PROCEDURE TestReverseStringSub@5128521(p_String@5128500 : Text[1024]) r_Int : Integer;
    VAR
      l_StringMgt@5128501 : Codeunit 5128519;
    BEGIN
      p_String := ReverseString(p_String);
      EXIT(STRLEN(p_String));
    END;

    PROCEDURE ReverseString@5128509(p_In@5128502 : Text[1024]) Result : Text[1024];
    VAR
      i@5128500 : Integer;
      l_Length@5128501 : Integer;
    BEGIN
      l_Length := STRLEN(p_In) + 1;

      FOR i := 1 TO l_Length - 1 DO
        Result[i] := p_In[l_Length-i];
    END;

    PROCEDURE MiddleCase@1000000000(p_StringToConvert@1000000000 : Text[250]) ConvertedString : Text[250];
    BEGIN
      ConvertedString :=
        UPPERCASE(COPYSTR(p_StringToConvert, 1, 1)) +
        LOWERCASE(COPYSTR(p_StringToConvert, 2));
    END;

    BEGIN
    END.
  }
}

Since we don’t do anything evil here my only advice is to initialize every return parameter with a default value. This seems to fix the bug.


    PROCEDURE ReverseString@5128509(p_In@5128502 : Text[1024]) Result : Text[1024];
    VAR
      i@5128500 : Integer;
      l_Length@5128501 : Integer;
    BEGIN
      Result := ''; // Init return value – this fixes the issue!
      l_Length := STRLEN(p_In) + 1;

      FOR i := 1 TO l_Length - 1 DO
        Result[i] := p_In[l_Length-i];
    END;

Interestingly I didn’t find a smaller sample which reproduces this memory issue.

Tags: ,

No Comments »

No comments yet.

RSS feed for comments on this post. | TrackBack URI

Leave a comment

XHTML ( You can use these tags): <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> .