views:

158

answers:

2

When I trim a multi-line textarea in JavaScript to a certain length (JS: .substring(0, x)), and that field is then posted back, checking the length in VB.NET will still find a length greater than the trim length from JavaScript (VB: .Length > x).

I have already determined this was a problem with line breaks, but I wanted to make sure no one else had to spend so long finding the answer (apparently it also applies to some implementations of JSP).

Somewhere in the whole ASP.NET scheme of things, a multi-line value is being massaged from the land of "\n" (vbLf) line breaks into the land of "\r\n" (vbCrLf) line breaks This difference in line breaks is the reason the lengths do not agree. Here is the simple way of addressing it in VB.NET (though a regex could probably do it to):

 SomeString = SomeString.Replace(vbCrLf, vbCr)

Handling it in VB.NET opens myself up to potential duplication and would still leave it easy to miss this logic when someone adds another textarea; handling it in JavaScript could do the same thing. Is there some way to keep VB.NET/ASP.NET from handling line breaks this way or is there some better way of making this a non-issue? The answer to this best-practices question would definitely be the correct answer to this question.

A: 

Welcome to the land of Unix line endings versus Windows OS based line endings.

Doesn't IIS have some sort of HTTP request filter or even a configuration option to not modify the request as it comes in? That would be the best answer.

Otherwise, search and replace is your best answer.

altCognito
+1  A: 

The culprit seems to be an internal type in System.Web.dll; System.Web.HttpMultipartContentTemplateParser. Using Reflector, I found this code;

private bool GetNextLine()
{
    int num = this._pos;
    this._lineStart = -1;
    while (num < this._length)
    {
        if (this._data[num] == 10)
        {
            this._lineStart = this._pos;
            this._lineLength = num - this._pos;
            this._pos = num + 1;
            if ((this._lineLength > 0) && (this._data[num - 1] == 13))
            {
                this._lineLength--;
            }
            break;
        }
        if (++num == this._length)
        {
            this._lineStart = this._pos;
            this._lineLength = num - this._pos;
            this._pos = this._length;
        }
    }
    return (this._lineStart >= 0);
}

Note some of the magic numbers, especially 10 and 13. These are vbLf and vbCr. It seems to me that this is processing the raw bytes that come in from the post, and 'a line' is considered to be anything ending with vbLf (10).

As the raw bytes are parsed (see the ParsePartData method, too) the compexities of vbcr and vblf are being cleaned out.

Ultimately, then, I think it's safe to just replace CrLF with LF again.

Steve Cooper