2

I am getting following error:

Arithmetic operation resulted in an overflow

on the code below:

Public Function DoEncode(ByVal aPassword As String, ByVal aPassword2 As String) As String
        Dim ascii As New ASCIIEncoding()
        Dim b As Byte() = ascii.GetBytes(aPassword)
        Dim b2 As Byte() = ascii.GetBytes(aPassword2)

        Dim iDiff As UInt32 = b2(0) - b(0)
        For i As Integer = 0 To b.Length - 1
            b(i) += CByte(iDiff)
        Next

        Return ascii.GetString(b)
    End Function

I have used the function in my login form:

Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click

        If UsernameTextBox.Text.Trim() = "" Then
            MessageBox.Show("Please enter your user id", "User ID", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return
        End If

        If PasswordTextBox.Text.Trim() = "" Then
            MessageBox.Show("Please enter your password", "User ID", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return
        End If

        If O.AppMan.DoLogin(UsernameTextBox.Text, PasswordTextBox.Text) Then
            DialogResult = System.Windows.Forms.DialogResult.OK
        End If
    End Sub

Upper code is used in:

Public Class TApplicationManager
    Public Class O
        Public Shared AppMan As New TApplicationManager()
    End Class
    Public Function DoEncode(ByVal aPassword As String, ByVal aPassword2 As String) As String
        Dim ascii As New ASCIIEncoding()
        Dim b As Byte() = ascii.GetBytes(aPassword)
        Dim b2 As Byte() = ascii.GetBytes(aPassword2)

        Dim iDiff As UInt32 = b2(0) - b(0)
        For i As Integer = 0 To b.Length - 1
            b(i) += CByte(iDiff)
        Next

        Return ascii.GetString(b)
    End Function

    Public Function DoLogin(ByVal strUser As String, ByVal strPwd As String) As Boolean
        Dim dtbUser As New DataTable()
        Dim dtbUserCare As New DataTable()
        Dim UserName As String
        Dim UserPass As String
        Dim cnn As New MySqlConnection(My.Settings.sys_dbConnectionString)
        Dim strLoginCare As String = "SELECT * FROM tblusers where Username = '" + strUser + "'"
        Dim daUser As New MySqlDataAdapter(strLoginCare, cnn)
        dtbUser.Clear()
        daUser.Fill(dtbUser)

        If dtbUser.Rows.Count = 0 Then
            MessageBox.Show("User does not exist", "User status", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return False
        End If

        Dim drwUser As DataRow = dtbUser.Rows(0)
        UserPass = drwUser("Password").ToString()
        UserName = drwUser("Username").ToString()

        Dim daUserCare As New MySqlDataAdapter(strLoginCare, cnn)
        dtbUserCare.Clear()
        daUserCare.Fill(dtbUserCare)

        If dtbUserCare.Rows.Count = 0 Then
            MessageBox.Show("Invalid user id", "User status", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return False
        End If

        Dim drwUserCare As DataRow = dtbUserCare.Rows(0)

        If drwUserCare("Password").ToString() <> DoEncode(strPwd, drwUserCare("Password").ToString()) Then
            MessageBox.Show("Invalid password. Please try again", "User status", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return False
        End If



        If drwUserCare("status").ToString() <> "Y" Then
            MessageBox.Show("User is not active", "User status", MessageBoxButtons.OK, MessageBoxIcon.[Stop])
            Return False
        End If

        UserPass = drwUserCare("Password").ToString()
        UserName = drwUserCare("Username").ToString()

        Return True
    End Function

End Class

Why am I getting this error?

KernelPanic
  • 2,328
  • 7
  • 47
  • 90
rowneyo
  • 54
  • 4
  • Perhaps use a long rather than an integer when looping around the bytes. – Shaun Nov 26 '15 at 07:59
  • Actually it's probably not that if it's just for the password. Don't you have a stack trace? Highlight or comment on what line that is throwing that exception. – Shaun Nov 26 '15 at 08:02
  • 1
    Did you know that when you get an error in VB.NET (and in any other programming language I am aware of -> impressive, isn't it?), it is associated with a specific line of the code? That is: instead of having to analyse the whole code, you can go directly to the given line triggering the error (which is usually notably smaller than the whole code). Could you please, now and in the future, provide this information (-> exact line triggering the error and exact error message) when posting a question about an error? We know already that you wrote a wrong code, don't need to show all of it to us :) – varocarbas Nov 26 '15 at 09:09
  • Sorry @shaun. The error is at line 5 I.e dim iDiff as UInt32 ...... – rowneyo Nov 26 '15 at 17:33

1 Answers1

1

Ok I'm going to take a stab it's this:

    Dim iDiff As UInt32 = b2(0) - b(0)
    For i As Integer = 0 To b.Length - 1
        b(i) += CByte(iDiff)
   Next

A) Uint32 can't be negative - and you are performing a subtraction between two bytes.

B) You are then casting that subtracted value to a Byte - bytes can't be negative, and from memory will throw this exception if you attempt to do so.

I don't actually understand what you're attempting to do in the above loop.

EDIT

As per your comment about this code working in c#, but not in VB, my answer still applies. The conversion is failing, because of either negative numbers or greater than 255.

c# does not automatically check for overflow errors where VB does.

You can disable this behaviour although changing the code to not overflow would be better in my opinion. You may get unexpected results.

See: https://msdn.microsoft.com/en-us/library/aa716336(v=vs.60).aspx

You can disable it by:

Project properties, enable Configuration Properties => Optimizations => Remove Integer Overflow Checks.

The same behaviour can be implemented in c# by wrapping the conversion / calculation in a 'checked' block.

Shaun
  • 933
  • 9
  • 16
  • I had even tried to interchange UInt32 with both Integer and also Long – rowneyo Nov 26 '15 at 17:36
  • And your error probably moved to the byte negativity. – Shaun Nov 26 '15 at 22:04
  • yes. Still haven't found a solution. In summary this is what the whole thing does. When a user logs in, the login in code does ASCIIEncoding on the password and the corresponding password stored in the database. Then compares the two byte values via subtraction. i dont know if this makes total sense – rowneyo Dec 13 '15 at 07:19
  • You should really use md5 or sha1 hashing instead of playing with bytes. – Shaun Dec 13 '15 at 07:28
  • the original code was in c# i did try to convert it to vb.net however i got the above error. i am making a modification to an existing program. Below is the c# code. and this works ok. public string DoEncode(string aPassword, string aPassword2) { ASCIIEncoding ascii = new ASCIIEncoding(); byte[] b = ascii.GetBytes(aPassword); byte[] b2 = ascii.GetBytes(aPassword2); int iDiff = b2[0] - b[0]; for (int i = 0; i < b.Length; i++) b[i] += (byte)iDiff; return ascii.GetString(b); } – rowneyo Dec 13 '15 at 10:40
  • Also, definitely only use an int, not a UInt – Shaun Dec 13 '15 at 13:06