From 4551e0670f1659dbb7d2a443eec274fe20a7d488 Mon Sep 17 00:00:00 2001 From: Philippe Saint-Pierre Date: Fri, 14 Aug 2009 15:49:07 +0000 Subject: [PATCH] Add input validation in Network preflet. Now, if the user attempt to enter an invalid IPv4 address in a field, when he clicks apply : * the focus goes back to the invalid field * it displays an error message into the window, at the bottom * it beeps * it doesn't save the change, of course DNS #2 is consider optional. The check is made with a regex. This should take care of ticket #4205. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32370 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/EthernetSettingsView.cpp | 51 ++++++++++++++++++- .../network/EthernetSettingsView.h | 8 +++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/preferences/network/EthernetSettingsView.cpp b/src/preferences/network/EthernetSettingsView.cpp index c3bda26881..a8bac00c7c 100644 --- a/src/preferences/network/EthernetSettingsView.cpp +++ b/src/preferences/network/EthernetSettingsView.cpp @@ -7,6 +7,7 @@ * Stephan Assmuß * Axel Dörfler * Hugo Santos + * Philippe Saint-Pierre */ #include "EthernetSettingsView.h" @@ -59,6 +60,8 @@ #include +#include + #include "AutoDeleter.h" @@ -164,6 +167,13 @@ EthernetSettingsView::EthernetSettingsView() layout->AddItem(fSecondaryDNSTextControl->CreateLabelLayoutItem(), 0, 6); layout->AddItem(fSecondaryDNSTextControl->CreateTextViewLayoutItem(), 1, 6); + fErrorMessage = new BStringView("error", ""); + fErrorMessage->SetAlignment(B_ALIGN_LEFT); + fErrorMessage->SetFont(be_bold_font); + fErrorMessage->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); + + layout->AddView(fErrorMessage, 1, 7); + // button group (TODO: move to window, but take care of // enabling/disabling) BGroupView* buttonGroup = new BGroupView(B_HORIZONTAL); @@ -486,6 +496,38 @@ EthernetSettingsView::_GetPath(const char* name, BPath& path) } +bool +MatchPattern(const char* string, const char* pattern) +{ + regex_t compiled; + bool result = regcomp(&compiled, pattern, REG_NOSUB | REG_EXTENDED) == 0 + && regexec(&compiled, string, 0, NULL, 0) == 0; + regfree(&compiled); + + return result; +} + + +bool +EthernetSettingsView::_ValidateControl(BTextControl* control) +{ + static const char* pattern = "^(25[0-5]|2[0-4][0-9]|[01][0-9]{2}|[0-9]" + "{1,2})(\\.(25[0-5]|2[0-4][0-9]|[01][0-9]{2}|[0-9]{1,2})){3}$"; + + if (control->IsEnabled() && !MatchPattern(control->Text(), pattern)) { + control->MakeFocus(); + BString errorMessage; + errorMessage << control->Label(); + errorMessage.RemoveLast(":"); + errorMessage << " is invalid"; + fErrorMessage->SetText(errorMessage.String()); + beep(); + return false; + } + return true; +} + + void EthernetSettingsView::MessageReceived(BMessage* message) { @@ -514,9 +556,16 @@ EthernetSettingsView::MessageReceived(BMessage* message) fRevertButton->SetEnabled(false); break; case kMsgApply: - _SaveConfiguration(); + if (_ValidateControl(fIPTextControl) + && _ValidateControl(fNetMaskTextControl) + && _ValidateControl(fGatewayTextControl) + && _ValidateControl(fPrimaryDNSTextControl) + && (strlen(fSecondaryDNSTextControl->Text()) == 0 + || _ValidateControl(fSecondaryDNSTextControl))) + _SaveConfiguration(); break; case kMsgChange: + fErrorMessage->SetText(""); fApplyButton->SetEnabled(true); break; default: diff --git a/src/preferences/network/EthernetSettingsView.h b/src/preferences/network/EthernetSettingsView.h index 3d26c9a913..07915cd9fb 100644 --- a/src/preferences/network/EthernetSettingsView.h +++ b/src/preferences/network/EthernetSettingsView.h @@ -16,10 +16,13 @@ #include #include +#include + class BButton; class BMenuField; class BPath; class BTextControl; +class BStringView; class EthernetSettingsView : public BView { @@ -46,6 +49,8 @@ private: void _ApplyControlsToConfiguration(); status_t _GetPath(const char* name, BPath& path); status_t _TriggerAutoConfig(const char* device); + + bool _ValidateControl(BTextControl* control); private: BButton* fApplyButton; @@ -60,6 +65,9 @@ private: BTextControl* fPrimaryDNSTextControl; BTextControl* fSecondaryDNSTextControl; + + BStringView* fErrorMessage; + // TODO: DNS settings do not belong here, do they? BObjectList fInterfaces; // TODO: the view should not know about the interfaces,