From c4c38ddf0fa6918eaa6232dd337652775f6157f7 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 21 Mar 2013 20:19:58 -0500 Subject: [PATCH] Use built in TQt3 security in KPasswordEdit This resolves several long standing bugs related to input and editing of text in KPasswordEdit widgets --- tdeui/kpassdlg.cpp | 210 +++++++++------------------------------------ tdeui/kpassdlg.h | 17 ++-- 2 files changed, 49 insertions(+), 178 deletions(-) diff --git a/tdeui/kpassdlg.cpp b/tdeui/kpassdlg.cpp index 64904c581..87df72f60 100644 --- a/tdeui/kpassdlg.cpp +++ b/tdeui/kpassdlg.cpp @@ -56,33 +56,6 @@ * Password line editor. */ -// BCI: Add a real d-pointer and put the int into that - -static TQPtrDict* d_ptr = 0; - -static void cleanup_d_ptr() { - delete d_ptr; -} - -static int * ourMaxLength( const KPasswordEdit* const e ) { - if ( !d_ptr ) { - d_ptr = new TQPtrDict; - d_ptr->setAutoDelete(true); - tqAddPostRoutine( cleanup_d_ptr ); - } - int* ret = d_ptr->find( (void*) e ); - if ( ! ret ) { - ret = new int; - d_ptr->replace( (void*) e, ret ); - } - return ret; -} - -static void delete_d( const KPasswordEdit* const e ) { - if ( d_ptr ) - d_ptr->remove( (void*) e ); -} - const int KPasswordEdit::PassLen = 200; class KPasswordDialog::KPasswordDialogPrivate @@ -114,191 +87,92 @@ KPasswordEdit::KPasswordEdit(TQWidget *parent, const char *name) TDEConfigGroupSaver saver(cfg, "Passwords"); const TQString val = cfg->readEntry("EchoMode", "OneStar"); - if (val == "ThreeStars") - m_EchoMode = ThreeStars; - else if (val == "NoEcho") - m_EchoMode = NoEcho; - else - m_EchoMode = OneStar; + if (val == "ThreeStars") { + setEchoMode(PasswordThreeStars); + } + else if (val == "NoEcho") { + setEchoMode(TQLineEdit::NoEcho); + } + else { + setEchoMode(TQLineEdit::Password); + } setInputMethodEnabled( true ); } KPasswordEdit::KPasswordEdit(TQWidget *parent, const char *name, int echoMode) - : TQLineEdit(parent, name), m_EchoMode(echoMode) + : TQLineEdit(parent, name) { + setEchoMode((TQLineEdit::EchoMode)echoMode); init(); } -KPasswordEdit::KPasswordEdit(EchoModes echoMode, TQWidget *parent, const char *name) - : TQLineEdit(parent, name), m_EchoMode(echoMode) +KPasswordEdit::KPasswordEdit(EchoMode echoMode, TQWidget *parent, const char *name) + : TQLineEdit(parent, name) { + setEchoMode(echoMode); init(); } -KPasswordEdit::KPasswordEdit(EchoMode echoMode, TQWidget *parent, const char *name) +KPasswordEdit::KPasswordEdit(EchoModes echoMode, TQWidget *parent, const char *name) : TQLineEdit(parent, name) - , m_EchoMode( echoMode == TQLineEdit::NoEcho ? NoEcho : OneStar ) { + if (echoMode == KPasswordEdit::NoEcho) { + setEchoMode(TQLineEdit::NoEcho); + } + else if (echoMode == KPasswordEdit::ThreeStars) { + setEchoMode(TQLineEdit::PasswordThreeStars); + } + else if (echoMode == KPasswordEdit::OneStar) { + setEchoMode(TQLineEdit::Password); + } init(); } void KPasswordEdit::init() { - setEchoMode(TQLineEdit::Password); // Just in case setAcceptDrops(false); - int* t = ourMaxLength(this); - *t = (PassLen - 1); // the internal max length - m_Password = new char[PassLen]; - m_Password[0] = '\000'; - m_Length = 0; } KPasswordEdit::~KPasswordEdit() { - memset(m_Password, 0, PassLen * sizeof(char)); - delete[] m_Password; - delete_d(this); } -void KPasswordEdit::insert(const TQString &txt) -{ - const TQCString localTxt = txt.local8Bit(); - const unsigned int lim = localTxt.length(); - const int m_MaxLength = maxPasswordLength(); - for(unsigned int i=0; i < lim; ++i) - { - const unsigned char ke = localTxt[i]; - if (m_Length < m_MaxLength) - { - m_Password[m_Length] = ke; - m_Password[++m_Length] = '\000'; - } - } - showPass(); +const char *KPasswordEdit::password() const { + return text().ascii(); } void KPasswordEdit::erase() { - m_Length = 0; - memset(m_Password, 0, PassLen * sizeof(char)); setText(""); } -void KPasswordEdit::focusInEvent(TQFocusEvent *e) +void KPasswordEdit::setMaxPasswordLength(int newLength) { - const TQString txt = text(); - setUpdatesEnabled(false); - TQLineEdit::focusInEvent(e); - setUpdatesEnabled(true); - setText(txt); + setMaxLength(newLength); } - -void KPasswordEdit::keyPressEvent(TQKeyEvent *e) +int KPasswordEdit::maxPasswordLength() const { - switch (e->key()) { - case Key_Return: - case Key_Enter: - case Key_Escape: - e->ignore(); - break; - case Key_Backspace: - case Key_Delete: - case 0x7f: // Delete - if (e->state() & (ControlButton | AltButton)) - e->ignore(); - else if (m_Length) { - m_Password[--m_Length] = '\000'; - showPass(); - } - break; - default: - const unsigned char ke = TQString(e->text()).local8Bit()[0]; - if (ke >= 32) { - insert(e->text()); - } else - e->ignore(); - break; - } + return maxLength(); } -bool KPasswordEdit::event(TQEvent *e) { - switch(e->type()) { - - case TQEvent::MouseButtonPress: - case TQEvent::MouseButtonRelease: - case TQEvent::MouseButtonDblClick: - case TQEvent::MouseMove: - case TQEvent::IMStart: - case TQEvent::IMCompose: - return true; //Ignore - - case TQEvent::IMEnd: - { - TQIMEvent* const ie = (TQIMEvent*) e; - if (!ie->text().isEmpty()) - insert( ie->text() ); - return true; - } - - case TQEvent::AccelOverride: - { - TQKeyEvent* const k = (TQKeyEvent*) e; - switch (k->key()) { - case Key_U: - if (k->state() & ControlButton) { - m_Length = 0; - m_Password[m_Length] = '\000'; - showPass(); - } - } - return true; // stop bubbling - } - - default: - // Do nothing - break; - } - return TQLineEdit::event(e); +void KPasswordEdit::insert( const TQString &str) { + TQLineEdit::insert(str); } -void KPasswordEdit::showPass() -{ - TQString tmp; - - switch (m_EchoMode) { - case OneStar: - tmp.fill('*', m_Length); - setText(tmp); - break; - case ThreeStars: - tmp.fill('*', m_Length*3); - setText(tmp); - break; - case NoEcho: default: - emit textChanged(TQString::null); //To update the password comparison if need be. - break; - } +void KPasswordEdit::keyPressEvent(TQKeyEvent *e) { + TQLineEdit::keyPressEvent(e); } -void KPasswordEdit::setMaxPasswordLength(int newLength) -{ - if (newLength >= PassLen) newLength = PassLen - 1; // belt and braces - if (newLength < 0) newLength = 0; - int* t = ourMaxLength(this); - *t = newLength; - while (m_Length > newLength) { - m_Password[m_Length] = '\000'; - --m_Length; - } - showPass(); +void KPasswordEdit::focusInEvent(TQFocusEvent *e) { + TQLineEdit::focusInEvent(e); } -int KPasswordEdit::maxPasswordLength() const -{ - return *(ourMaxLength(this)); +bool KPasswordEdit::event(TQEvent *e) { + return TQLineEdit::event(e); } + /* * Password dialog. */ @@ -306,7 +180,7 @@ int KPasswordEdit::maxPasswordLength() const KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, TQWidget *parent, const char *name) : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn, - Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate) + Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) { d->iconName = "password"; init(); @@ -315,7 +189,7 @@ KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, const TQString& icon, TQWidget *parent, const char *name ) : KDialogBase(parent, name, true, "", Ok|Cancel|extraBttn, - Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate) + Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) { if ( icon.stripWhiteSpace().isEmpty() ) d->iconName = "password"; @@ -327,7 +201,7 @@ KPasswordDialog::KPasswordDialog(Types type, bool enableKeep, int extraBttn, con KPasswordDialog::KPasswordDialog(int type, TQString prompt, bool enableKeep, int extraBttn) : KDialogBase(0L, "Password Dialog", true, "", Ok|Cancel|extraBttn, - Ok, true), m_Keep(enableKeep? 1 : 0), m_keepWarnLbl(0), m_Type(type), d(new KPasswordDialogPrivate) + Ok, true), m_Keep(enableKeep? 1 : 0), m_Type(type), m_keepWarnLbl(0), d(new KPasswordDialogPrivate) { d->iconName = "password"; init(); diff --git a/tdeui/kpassdlg.h b/tdeui/kpassdlg.h index 2d124b01f..f90a83f08 100644 --- a/tdeui/kpassdlg.h +++ b/tdeui/kpassdlg.h @@ -57,7 +57,7 @@ public: */ KPasswordEdit(EchoMode echoMode, TQWidget *parent, const char *name); - /** + /** * Constructs a password input widget using echoMode as "echo mode". * Note that echoMode is a KPasswordEdit::EchoModes. * @since 3.2 @@ -79,7 +79,7 @@ public: * Returns the password. The memory is freed in the destructor * so you should make a copy. */ - const char *password() const { return m_Password; } + const char *password() const; /** * Erases the current password. @@ -92,8 +92,6 @@ public: * Set the current maximum password length. If a password longer than the limit * specified is currently entered, it is truncated accordingly. * - * The length is capped to lie between 0 and 199 inclusive. - * * @param newLength: The new maximum password length * @since 3.4 */ @@ -118,10 +116,6 @@ protected: private: void init(); - void showPass(); - - char *m_Password; - int m_EchoMode, m_Length; }; @@ -403,12 +397,15 @@ private: void init(); void erase(); - int m_Keep, m_Type, m_Row; + int m_Keep; + int m_Type; + int m_Row; TQLabel *m_pHelpLbl; TQLabel *m_keepWarnLbl; TQGridLayout *m_pGrid; TQWidget *m_pMain; - KPasswordEdit *m_pEdit, *m_pEdit2; + KPasswordEdit *m_pEdit; + KPasswordEdit *m_pEdit2; protected: virtual void virtual_hook( int id, void* data );