Bug 1345767 - Part 7: Factor HasBadInput() out of HTMLInputElement. r=smaug

MozReview-Commit-ID: AUdI2dKMh4U

--HG--
extra : rebase_source : 83a5ce2f2adfc18594ab82a8de35ec8ff90652f2
This commit is contained in:
Jessica Jong 2017-05-04 15:43:21 +08:00
parent 30c9b6fbb3
commit 9acf65dee9
8 changed files with 66 additions and 87 deletions

View File

@ -7527,96 +7527,10 @@ HTMLInputElement::HasStepMismatch(bool aUseZeroIfValueNaN) const
return mInputType->HasStepMismatch(aUseZeroIfValueNaN);
}
/**
* Takes aEmail and attempts to convert everything after the first "@"
* character (if anything) to punycode before returning the complete result via
* the aEncodedEmail out-param. The aIndexOfAt out-param is set to the index of
* the "@" character.
*
* If no "@" is found in aEmail, aEncodedEmail is simply set to aEmail and
* the aIndexOfAt out-param is set to kNotFound.
*
* Returns true in all cases unless an attempt to punycode encode fails. If
* false is returned, aEncodedEmail has not been set.
*
* This function exists because ConvertUTF8toACE() splits on ".", meaning that
* for 'user.name@sld.tld' it would treat "name@sld" as a label. We want to
* encode the domain part only.
*/
static bool PunycodeEncodeEmailAddress(const nsAString& aEmail,
nsAutoCString& aEncodedEmail,
uint32_t* aIndexOfAt)
{
nsAutoCString value = NS_ConvertUTF16toUTF8(aEmail);
*aIndexOfAt = (uint32_t)value.FindChar('@');
if (*aIndexOfAt == (uint32_t)kNotFound ||
*aIndexOfAt == value.Length() - 1) {
aEncodedEmail = value;
return true;
}
nsCOMPtr<nsIIDNService> idnSrv = do_GetService(NS_IDNSERVICE_CONTRACTID);
if (!idnSrv) {
NS_ERROR("nsIIDNService isn't present!");
return false;
}
uint32_t indexOfDomain = *aIndexOfAt + 1;
const nsDependentCSubstring domain = Substring(value, indexOfDomain);
bool ace;
if (NS_SUCCEEDED(idnSrv->IsACE(domain, &ace)) && !ace) {
nsAutoCString domainACE;
if (NS_FAILED(idnSrv->ConvertUTF8toACE(domain, domainACE))) {
return false;
}
value.Replace(indexOfDomain, domain.Length(), domainACE);
}
aEncodedEmail = value;
return true;
}
bool
HTMLInputElement::HasBadInput() const
{
if (mType == NS_FORM_INPUT_NUMBER) {
nsAutoString value;
GetNonFileValueInternal(value);
if (!value.IsEmpty()) {
// The input can't be bad, otherwise it would have been sanitized to the
// empty string.
NS_ASSERTION(!GetValueAsDecimal().isNaN(), "Should have sanitized");
return false;
}
nsNumberControlFrame* numberControlFrame =
do_QueryFrame(GetPrimaryFrame());
if (numberControlFrame &&
!numberControlFrame->AnonTextControlIsEmpty()) {
// The input the user entered failed to parse as a number.
return true;
}
return false;
}
if (mType == NS_FORM_INPUT_EMAIL) {
// With regards to suffering from bad input the spec says that only the
// punycode conversion works, so we don't care whether the email address is
// valid or not here. (If the email address is invalid then we will be
// suffering from a type mismatch.)
nsAutoString value;
nsAutoCString unused;
uint32_t unused2;
GetNonFileValueInternal(value);
HTMLSplitOnSpacesTokenizer tokenizer(value, ',');
while (tokenizer.hasMoreTokens()) {
if (!PunycodeEncodeEmailAddress(tokenizer.nextToken(), unused, &unused2)) {
return true;
}
}
return false;
}
return false;
return mInputType->HasBadInput();
}
void

View File

@ -133,6 +133,12 @@ InputType::GetStepBase() const
return mInputElement->GetStepBase();
}
nsIFrame*
InputType::GetPrimaryFrame() const
{
return mInputElement->GetPrimaryFrame();
}
void
InputType::DropReference()
{
@ -188,6 +194,12 @@ InputType::HasStepMismatch(bool aUseZeroIfValueNaN) const
return false;
}
bool
InputType::HasBadInput() const
{
return false;
}
nsresult
InputType::MinMaxStepAttrChanged()
{

View File

@ -28,6 +28,7 @@ class HTMLInputElement;
} // namespace mozilla
struct DoNotDelete;
class nsIFrame;
/**
* A common superclass for different types of a HTMLInputElement.
@ -57,6 +58,7 @@ public:
virtual bool IsRangeOverflow() const;
virtual bool IsRangeUnderflow() const;
virtual bool HasStepMismatch(bool aUseZeroIfValueNaN) const;
virtual bool HasBadInput() const;
virtual nsresult MinMaxStepAttrChanged();
@ -103,6 +105,11 @@ protected:
*/
mozilla::Decimal GetStepBase() const;
/**
* Get the primary frame for the input element.
*/
nsIFrame* GetPrimaryFrame() const;
mozilla::dom::HTMLInputElement* mInputElement;
};

View File

@ -7,6 +7,7 @@
#include "NumericInputTypes.h"
#include "mozilla/dom/HTMLInputElement.h"
#include "nsNumberControlFrame.h"
#include "nsTextEditorState.h"
bool
@ -86,6 +87,28 @@ NumberInputType::IsValueMissing() const
return IsValueEmpty();
}
bool
NumberInputType::HasBadInput() const
{
nsAutoString value;
GetNonFileValueInternal(value);
if (!value.IsEmpty()) {
// The input can't be bad, otherwise it would have been sanitized to the
// empty string.
NS_ASSERTION(!mInputElement->GetValueAsDecimal().isNaN(),
"Should have sanitized");
return false;
}
nsNumberControlFrame* numberControlFrame =
do_QueryFrame(GetPrimaryFrame());
if (numberControlFrame &&
!numberControlFrame->AnonTextControlIsEmpty()) {
// The input the user entered failed to parse as a number.
return true;
}
return false;
}
/* input type=range */
nsresult
RangeInputType::MinMaxStepAttrChanged()

View File

@ -35,6 +35,7 @@ public:
}
bool IsValueMissing() const override;
bool HasBadInput() const override;
private:
explicit NumberInputType(mozilla::dom::HTMLInputElement* aInputElement)

View File

@ -136,6 +136,26 @@ EmailInputType::HasTypeMismatch() const
!IsValidEmailAddressList(value) : !IsValidEmailAddress(value);
}
bool
EmailInputType::HasBadInput() const
{
// With regards to suffering from bad input the spec says that only the
// punycode conversion works, so we don't care whether the email address is
// valid or not here. (If the email address is invalid then we will be
// suffering from a type mismatch.)
nsAutoString value;
nsAutoCString unused;
uint32_t unused2;
GetNonFileValueInternal(value);
HTMLSplitOnSpacesTokenizer tokenizer(value, ',');
while (tokenizer.hasMoreTokens()) {
if (!PunycodeEncodeEmailAddress(tokenizer.nextToken(), unused, &unused2)) {
return true;
}
}
return false;
}
/* static */ bool
EmailInputType::IsValidEmailAddressList(const nsAString& aValue)
{

View File

@ -105,6 +105,7 @@ public:
}
bool HasTypeMismatch() const override;
bool HasBadInput() const override;
private:
explicit EmailInputType(mozilla::dom::HTMLInputElement* aInputElement)

View File

@ -30,6 +30,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
LOCAL_INCLUDES += [
'/dom/base',
'/dom/html',
'/layout/forms',
]
FINAL_LIBRARY = 'xul'