Menu

#781 Validation causes wrong change history for Custom Fields

None
closed
None
7
2015-02-13
2012-06-18
No

Version 3.5.5 and 3.5.6

0. Go to demo, and login as a guest:
http://ifdefined.com/btnet/

1. Create new bug:
Description: TEST change history
Project: DemoProject
Sample custom field: 1
(enter '1' into 'Sample custom field')
Click 'Create' button

2. Now edit bug:
Enter '2' into 'Sample custom field:'
Delete Description, so the validation can work
[NOTE: If you have custom validation, the result will be the same.]
c) Click 'Update' button
Bug is not being saved. Short Description is required.

3. Fix bug edition, so the changes can be saved:
Enter 'TEST change history' into 'Description' field.
Enter '3' into 'Sample custom field:'
Press 'Update' button.

BUG: An untrue entry shows in the change history:
changed Sample custom field from "2" to "3"

Should be: from "1" to "3"

Example:
http://ifdefined.com/btnet/edit_bug.aspx?id=16599

-=====================-

Here is a comment by Piotr Owsiak - The Best .NET Developer (Thanks Piotr!) :-)

Standard fields are saved only during the first request to the site (!IsPostBack) with this code:

        // save current values in previous, so that later we can write the audit trail when things change
        prev\_short\_desc.Value = \(string\) dr\["short\_desc"\];
        prev\_tags.Value = \(string\) dr\["bg\_tags"\];
        prev\_project.Value = Convert.ToString\(\(int\)dr\["project"\]\);
        prev\_project\_name.Value = Convert.ToString\(dr\["current\_project"\]\);
        prev\_org.Value = Convert.ToString\(\(int\)dr\["organization"\]\);
        prev\_org\_name.Value = Convert.ToString\(dr\["og\_name"\]\);
        prev\_category.Value = Convert.ToString\(\(int\)dr\["category"\]\);
        prev\_priority.Value = Convert.ToString\(\(int\)dr\["priority"\]\);
        prev\_assigned\_to.Value = Convert.ToString\(\(int\)dr\["assigned\_to\_user"\]\);
        prev\_assigned\_to\_username.Value = Convert.ToString\(dr\["assigned\_to\_username"\]\);
        prev\_status.Value = Convert.ToString\(\(int\)dr\["status"\]\);
        prev\_udf.Value = Convert.ToString\(\(int\)dr\["udf"\]\);
        prev\_pcd1.Value = \(string\) dr\["bg\_project\_custom\_dropdown\_value1"\];
        prev\_pcd2.Value = \(string\) dr\["bg\_project\_custom\_dropdown\_value2"\];
        prev\_pcd3.Value = \(string\) dr\["bg\_project\_custom\_dropdown\_value3"\];

while custom fields are save with this code only on the first requst (!IsPostBack):

        foreach \(DataRow drcc in ds\_custom\_cols.Tables\[0\].Rows\)
        \{
            string column\_name = \(string\)drcc\["name"\];
            if \(security.user.dict\_custom\_field\_permission\_level\[column\_name\] \!= Security.PERMISSION\_NONE\)
            \{
                string val = btnet.Util.format\_db\_value\(dr\[column\_name\]\);
                hash\_custom\_cols.Add\(column\_name, val\);
                hash\_prev\_custom\_cols.Add\(column\_name, val\);
            \}
        \}

and with this code on each post back:

    // Fetch the values of the custom columns from the Request and stash them in a hash table.

    foreach \(DataRow drcc in ds\_custom\_cols.Tables\[0\].Rows\)
    \{
        string column\_name = \(string\)drcc\["name"\];

        if \(security.user.dict\_custom\_field\_permission\_level\[column\_name\] \!= Security.PERMISSION\_NONE\)
        \{
            if \(permission\_level == Security.PERMISSION\_ALL || id == 0\)
            \{
                hash\_custom\_cols.Add\(column\_name, Request\[column\_name\]\);
            \}
            else
            \{
                hash\_custom\_cols.Add\(column\_name, Request\["prev\_" + column\_name\]\);
            \}
            hash\_prev\_custom\_cols.Add\(column\_name, Request\["prev\_" + column\_name\]\);
        \}
    \}

this is possible because hash_custom_cols is stored in inputs on every response with this code:

// create the "Prev" fields for the custom columns so that we
// can create an audit trail of their changes.

foreach \(string column\_name in hash\_custom\_cols.Keys\)
\{
    Response.Write \("<input type=hidden name=\"prev\_"\);
    Response.Write\(column\_name\);
    Response.Write \("\""\);

    // output a date field according to the specified format
    Response.Write \(" value=\""\);
    //modified by CJU on jan 9 2008
    Response.Write\(HttpUtility.HtmlEncode\(hash\_custom\_cols\[column\_name\]\)\);
    //modified by CJU on jan 9 2008
    Response.Write \("\">\n"\);
\}

The problem is that hash_custom_cols is filled in from the last Request when permission_level == Security.PERMISSION_ALL or id == 0
and on the response input with prev_MyCustomField1 will contain not what was in the DB but what has been selected on the pager before request to the server.
This means that in case of validation errors there's a window for this bug to manifest itself via incorrect comments:
"field XXX changed from YYY to ZZZ"
cause YYY is not what was in the DB but what was on the page.
This code saves the "changed from..." message:

        do\_update = true;
        sql += base\_sql.Replace\(
            "$3",
            "changed " + column\_name + " from \"" + before.Trim\(\).Replace\("'", "''"\) + "\" to \"" + after.Trim\(\).Replace\("'", "''"\) + "\""\);

        hash\_prev\_custom\_cols\[column\_name\] = hash\_custom\_cols\[column\_name\];

Discussion

  • Mateusz Dobrowolny

    • summary: Validation causes Custom Fields wrong change history --> Validation causes wrong change history for Custom Fields
     
  • Corey Trager

    Corey Trager - 2012-06-18

    I'll look at this tonight. Thanks again guys.

     
  • Corey Trager

    Corey Trager - 2012-06-18
    • assigned_to: nobody --> ctrager
    • priority: 5 --> 7
     
  • Corey Trager

    Corey Trager - 2012-06-19

    Thanks so much. What direction should the fix take? What do you recommend?

     
  • Corey Trager

    Corey Trager - 2013-01-27

    Fixed in version 3.6.1, but there are big changes in edit_bug.aspx, so I might have broken other things....

     
  • Corey Trager

    Corey Trager - 2013-01-27
    • status: open --> closed
    • milestone: -->
     

Log in to post a comment.