Problem with email validation: Invalid procedure call or argument: 'Mid' - asp-classic

I tried to control email address and reviewer's name with the following code but I received this error.
Microsoft VBScript runtime error '800a0005'
Invalid procedure call or argument: 'Mid'
Cant I compare Mid(REVIEWEREMAIL, InStr(1, REVIEWEREMAIL, "#", 1), 1) to "#"?
If Len(REVIEWERNAME) < 2 Then
with response
.write "Error! Please fill in valid name. <br />"
end with
ElseIf Len(REVIEWEREMAIL) < 3 Then
with response
.write "Error! Please fill in valid email address. <br />"
end with
ElseIf Mid(REVIEWEREMAIL, InStr(1, REVIEWEREMAIL, "#", 1), 1) <> "#" Then
with response
.write "Error! Please fill in valid email address. <br />"
end with
Else
insert...
End If

You can simplify that last ElseIf like this:
ElseIf InStr(REVIEWEREMAIL, "#", vbTextCompare) = 0 Then
Because as written, you're solely checking if there is a # in the email address provided.
If you're concerned about further validating the email addresses you get, there is a great deal written about using regular expressions to validate email addresses. One example: http://www.codetoad.com/asp_email_reg_exp.asp

The likely reason is that REVIEWEREMAIL is null -- in which case your first IF condition isn't going to catch it as intended. Len() of a null doesn't return an integer 0.
The "classic" ASP cheat for that is to change your null variable to an empty string with something like
REVIEWEREMAIL = REVIEWEREMAIL & ""
which will give back LEN = 0
Beyond that, you may want to look for a regular expression online that will check for valid email values.

Related

Is possible to add a String.contains more than one value?

I want to make a control, when I create a companyId, to not permit to create id with special characters like, (&), (/), (), (ñ), ('):
If txtIdCompany.Text.Contains("&") Then
// alert error message
End If
But I can't do this:
If txtIdCompany.Text.Contains("&", "/", "\") Then
// alert error message
End If
How can I check more than one string in the same line?
You can use collections like a Char() and Enumerable.Contains. Since String implements IEnumerable(Of Char) even this concise and efficient LINQ query works:
Dim disallowed = "&/\"
If disallowed.Intersect(txtIdCompany.Text).Any() Then
' alert error message
End If
here's a similar approach using Enumerable.Contains:
If txtIdCompany.Text.Any(AddressOf disallowed.Contains) Then
' alert error message
End If
a third option using String.IndexOfAny:
If txtIdCompany.Text.IndexOfAny(disallowed.ToCharArray()) >= 0 Then
' alert error message
End If
If txtIdCompany.Text.Contains("&") Or txtIdCompany.Text.Contains("\") Or txtIdCompany.Text.Contains("/") Then
// alert error message
End If

When comparing two identical strings they return as different

I have the first password from a text box:
pwtextbox = TextBox2.Text
and the other one I am reading from a DB Table:
pwdatabase = SQLdr("pw")
I've tried to compare them using '=', StrComp, and strings.compare and they always, no matter what, come as different
While SQLdr.Read() 'While Data is Present
pwdatabase = SQLdr("pw") 'pwdatabase is equal db entry
Response.Write(pwtextbox & "=" & pwdatabase & "?<br>") 'is mickey=mickey?
If StrComp(pwtextbox, pwdatabase) = 0 Then
Response.Write("login successful")
Response.Write(pwdatabase & "is the pass")
Else
Response.Write("wrong password. ")
Response.Write(TextBox2.Text & " is the wrong pass. the right password is " & pwdatabase)
End If
End While
the onscreen display outputs as follow:
mickey=mickey?
wrong password.
mickey is the wrong password. the right password is mickey.
I can't seem to understand!
especially when I see on the screen that the two strings are identical, I still get this false positive...
can you see what I'm missing?

How to handle ampersands in URL parameters?

I am having the following issue:
I am using an application that allows users to concatenate text to build a URL that passes parameters to an ASP page via GET method, i.e. something like:
http://myhostname/process.asp?param1=value1&param2=value2
Problem is value1 and value2 can contain the ampersand symbol, which is not interpreted as a text character.
The most popular solution to this issue is to encode the URL, which is not an option for me because I cannot modify the program that builds the URL. I can modify the process.asp page, but not the program that concatenates the text fields and builds the URL.
Things I've tried to search for are:
How to encode a URL using javascript directly in the browser
How to change IIS default behaviour when reading an &
Alternative ways to pass parameters, i.e. something like passing them as a single string of characters separated with pipes
Hope you can give me some guidance.
You can read the entire query string and parse it yourself, like this:
q = Request.QueryString
a = Split(q, "=")
i = 1
For Each s In a
If i mod 2 = 0 Then
If InStr(s, "&") <> InStrRev(s, "&") Then
Response.Write "Value: " & Left(s, InStrRev(s, "&") - 1) & "<br/>"
hidingParam = Right(s, Len(s) - InStrRev(s, "&"))
Response.Write "PAramName: " & hidingParam & "<br/>"
i = i + 1
Else
Response.Write "Value: " & s & "<br/>"
End If
Else
Response.Write "PAramName: " & s & "<br/>"
End If
i = i + 1
Next
Result:
URL: ...?Q=abc&def&P=123 produces
PAramName: Q Value: abc&def PAramName: P Value: 123
Note that this is less than robust. I am only illustrating my idea. I didn't test with no &.
It also doens't handle multiple "=" characters (if that's a possiblity as well).
If there are 2 (or more) ampersands in-between the equals, then only the last one is a parameter separator. So, using your URL above, and assuming that value1 = "abc&def", and value2 = "123", then the URL will look like:
http://myhostname/process.asp?param1=abc&def&param2=123
Notice there's 2 ampersands in-between the 2 equals. The last one will be your parameter separator, the rest are part of the value. And any ampersands after the last equals are also part of the value.
You'll have to dissect the incoming URL and apply the appropriate logic.

converting code into classic asp

I want to convert the below string into classic asp code can any one help
email has some value but it is not going inside the Loop
Can any one help me.
If (IsEmpty(email) And IsNull(email)) Then
EndIf
The code looks like its VBScript already so there is no "conversion" needed, however the code is faulty. Should be:
If IsEmpty(email) Or IsNull(email) Then
End If
a variable cannot both be empty and contain a Null at the same time hence the orginal conditional expression was always false.
You could always try:
If IsEmpty(email) = True Then
'uninitialized
ElseIf IsNull(email) = True Then
'contains null value
ElseIf email = ""
'contains zero length string
Else
'Response.Write email
'MsgBox email
End If
In most cases I try to code so that the variable is guaranteed to be initialized so you don't need to run the IsEmpty check.
Option Explicit
Dim email
email = ""
Why don't you just check the length of the email variable:
If Len(Trim(email)) > 0 Then
Else
YOUR CODE HERE
End If

Best Regular Expression for Email Format Validation with ASP.NET 3.5 Validation

I've used both of the following Regular Expressions for testing for a valid email expression with ASP.NET validation controls. I was wondering which is the better expression from a performance standpoint, or if someone has better one.
- \w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*
- ^([0-9a-zA-Z]([-\.\w]*[0-9a-zA-Z])*#([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,9})$
I'm trying avoid the "exponentially slow expression" problem described on the BCL Team Blog.
UPDATE
Based on feedback I ended up creating a function to test if an email is valid:
Public Function IsValidEmail(ByVal emailString As String, Optional ByVal isRequired As Boolean = False) As Boolean
Dim emailSplit As String()
Dim isValid As Boolean = True
Dim localPart As String = String.Empty
Dim domainPart As String = String.Empty
Dim domainSplit As String()
Dim tld As String
If emailString.Length >= 80 Then
isValid = False
ElseIf emailString.Length > 0 And emailString.Length < 6 Then
'Email is too short
isValid = False
ElseIf emailString.Length > 0 Then
'Email is optional, only test value if provided
emailSplit = emailString.Split(CChar("#"))
If emailSplit.Count <> 2 Then
'Only 1 # should exist
isValid = False
Else
localPart = emailSplit(0)
domainPart = emailSplit(1)
End If
If isValid = False OrElse domainPart.Contains(".") = False Then
'Needs at least 1 period after #
isValid = False
Else
'Test Local-Part Length and Characters
If localPart.Length > 64 OrElse ValidateString(localPart, ValidateTests.EmailLocalPartSafeChars) = False OrElse _
localPart.StartsWith(".") OrElse localPart.EndsWith(".") OrElse localPart.Contains("..") Then
isValid = False
End If
'Validate Domain Name Portion of email address
If isValid = False OrElse _
ValidateString(domainPart, ValidateTests.HostNameChars) = False OrElse _
domainPart.StartsWith("-") OrElse domainPart.StartsWith(".") OrElse domainPart.Contains("..") Then
isValid = False
Else
domainSplit = domainPart.Split(CChar("."))
tld = domainSplit(UBound(domainSplit))
' Top Level Domains must be at least two characters
If tld.Length < 2 Then
isValid = False
End If
End If
End If
Else
'If no value is passed review if required
If isRequired = True Then
isValid = False
Else
isValid = True
End If
End If
Return isValid
End Function
Notes:
IsValidEmail is more restrictive about characters allowed then the RFC, but it doesn't test for all possible invalid uses of those characters
If you're wondering why this question is generating so little activity, it's because there are so many other issues that should be dealt with before you start thinking about performance. Foremost among those is whether you should be using regexes to validate email addresses at all--and the consensus is that you should not. It's much trickier than most people expect, and probably pointless anyway.
Another problem is that your two regexes vary hugely in the kinds of strings they can match. For example, the second one is anchored at both ends, but the first isn't; it would match ">>>>foo#bar.com<<<<" because there's something that looks like an email address embedded in it. Maybe the framework forces the regex to match the whole string, but if that's the case, why is the second one anchored?
Another difference is that the first regex uses \w throughout, while the second uses [0-9a-zA-Z] in many places. In most regex flavors, \w matches the underscore in addition to letters and digits, but in some (including .NET) it also matches letters and digits from every writing system known to Unicode.
There are many other differences, but that's academic; neither of those regexes is very good. See here for a good discussion of the topic, and a much better regex.
Getting back to the original question, I don't see a performance problem with either of those regexes. Aside from the nested-quantifiers anti-pattern cited in that BCL blog entry, you should also watch out for situations where two or more adjacent parts of the regex can match the same set of characters--for example,
([A-Za-z]+|\w+)#
There's nothing like that in either of the regexes you posted. Parts that are controlled by quantifiers are always broken up by other parts that aren't quantified. Both regexes will experience some avoidable backtracking, but there are many better reasons than performance to reject them.
EDIT: So the second regex is subject to catastrophic backtracking; I should have tested it thoroughly before shooting my mouth off. Taking a closer look at that regex, I don't see why you need the outer asterisk in the first part:
[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*
All that bit does is make sure the first and last characters are alphanumeric while allowing some additional characters in between. This version does the same thing, but it fails much more quickly when no match is possible:
[0-9a-zA-Z][-.\w]*[0-9a-zA-Z]
That would probably suffice to eliminate the backtracking problem, but you could also make the part after the "#" more efficient by using an atomic group:
(?>(?:[0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+)[a-zA-Z]{2,9}
In other words, if you've matched all you can of substrings that look like domain components with trailing dots, and the next part doesn't look like a TLD, don't bother backtracking. The first character you would have to give up is the final dot, and you know [a-zA-Z]{2,9} won't match that.
We use this RegEx which has been tested in-house against 1.5 million addresses. It correctly identifies better than 98% of ours, but there are some formats that I'm aware of that it would error on.
^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$
We also make sure that there are no EOL characters in the data since an EOL can fake out this RegEx. Our Function:
Public Function IsValidEmail(ByVal strEmail As String) As Boolean
' Check An eMail Address To Ensure That It Is Valid
Const cValidEmail = "^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$" ' 98% Of All Valid eMail Addresses
IsValidEmail = False
' Take Care Of Blanks, Nulls & EOLs
strEmail = Replace(Replace(Trim$(strEmail & " "), vbCr, ""), vbLf, "")
' Blank eMail Is Invalid
If strEmail = "" Then Exit Function
' RegEx Test The eMail Address
Dim regEx As New System.Text.RegularExpressions.Regex(cValidEmail)
IsValidEmail = regEx.IsMatch(strEmail)
End Function
I am a newbie, but I tried the following and it seemed to have limited the ".xxx" to only two occurrences or less, after the symbol '#'.
^([a-zA-Z0-9]+[a-zA-Z0-9._%-]*#(?:[a-zA-Z0-9-])+(\.+[a-zA-Z]{2,4}){1,2})$
Note: I had to substitute single '\' with double '\\' as I am using this reg expr in R.
These don't check for all allowable email addresses according to the email address RFC.
I let MS to do the work for me:
Public Function IsValidEmail(ByVal emailString As String) As Boolean
Dim retval As Boolean = True
Try
Dim address As New System.Net.Mail.MailAddress(emailString)
Catch ex As Exception
retval = False
End Try
Return retval
End Function
For server side validation, I found Phil Haack's solution to be one of the better ones. His attempt was to stick to the RFC:
string pattern = #"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
+ #"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
+ #"#[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
return regex.IsMatch(emailAddress);
Details:
http://blog.degree.no/2013/01/email-validation-finally-a-net-regular-expression-that-works/
Just to contribute, I am using this regex.
^([a-zA-Z0-9]+[a-zA-Z0-9._%-]*#(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,4})$
The thing about it is the specifications are changing with each domain extension that is introduced.
You sit here mod your regex, test, test, test, and more testing. You finally get what you "think" is accurate then the specification changes... You update your regex to account for what the new requirements are..
Then someone enters aa#aa.aa and you've done all that work for what? It walks through your fancy regex.. bummer!
You may as well just check for a single #, and a "." and move on. I assure you, you will not get someones email if they do not want to give it up. You'll get garbage or their hotmail account they never check and couldn't care less about.
I've seen in many cases this goes horribly wrong and a client calls up because their own email address is rejected because of a poorly crafted regex check. Which as mentioned shouldn't have even been attempted.
TextBox :-
<asp:TextBox ID="txtemail" runat="server" CssClass="form-control pantxt" Placeholder="Enter Email Address"></asp:TextBox>
Required Filed validator:
<asp:RequiredFieldValidator ID="RequiredFieldValidator9" runat="server" ControlToValidate="txtemail" ErrorMessage="Required"></asp:RequiredFieldValidator>
Regular Expression for email validation :
<asp:RegularExpressionValidator ID="validateemail" runat="server" ControlToValidate="txtemail" ValidationExpression="\w+([-+.']\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*" ErrorMessage="Invalid Email"></asp:RegularExpressionValidator>
Use this regular expression for email validation in asp.net

Resources