From e94ad1e24d1fafa275a99a7edad869d2a1a825d4 Mon Sep 17 00:00:00 2001 From: Stefano Ceccherini Date: Fri, 31 Aug 2007 07:39:18 +0000 Subject: [PATCH] If typing is hidden, don't reply to B_COPY or B_CUT messages, but beep() in this case. Note that the public methods still let you copy and cut the real text. Also prevented stealing passwords via scripting (not tested, though). Fixes bug #1354 Got rid of the _BTextGapBuffer_::[] operator since using it creates less readable code. Also Implemented _BTextGapBuffer_::RealText() and used it instead of Text() inside BTextView. Will make sense later. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22129 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/TextView.cpp | 74 ++++++++++--------- .../textview_support/TextGapBuffer.cpp | 54 +++++++++----- .../textview_support/TextGapBuffer.h | 6 +- 3 files changed, 78 insertions(+), 56 deletions(-) diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index eadb17595e..1f5d50421b 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -773,11 +773,17 @@ BTextView::MessageReceived(BMessage *message) switch (message->what) { case B_CUT: - Cut(be_clipboard); + if (!IsTypingHidden()) + Cut(be_clipboard); + else + beep(); break; case B_COPY: - Copy(be_clipboard); + if (!IsTypingHidden()) + Copy(be_clipboard); + else + beep(); break; case B_PASTE: @@ -845,36 +851,29 @@ BTextView::MessageReceived(BMessage *message) BView::MessageReceived(message); break; } - + + BMessage reply; + bool handled = false; switch(message->what) { case B_GET_PROPERTY: - { - BMessage reply; - GetProperty(&specifier, specifier.what, property, &reply); - message->SendReply(&reply); + handled = GetProperty(&specifier, specifier.what, property, &reply); break; - } case B_SET_PROPERTY: - { - BMessage reply; - SetProperty(&specifier, specifier.what, property, &reply); - message->SendReply(&reply); + handled = SetProperty(&specifier, specifier.what, property, &reply); break; - } case B_COUNT_PROPERTIES: - { - BMessage reply; - CountProperties(&specifier, specifier.what, property, &reply); - message->SendReply(&reply); + handled = CountProperties(&specifier, specifier.what, property, &reply); break; - } default: break; } - + if (handled) + message->SendReply(&reply); + else + BView::MessageReceived(message); break; } @@ -1132,7 +1131,7 @@ BTextView::Delete(int32 startOffset, int32 endOffset) const char * BTextView::Text() const { - return fText->Text(); + return fText->RealText(); } @@ -1164,7 +1163,7 @@ BTextView::ByteAt(int32 offset) const if (offset < 0 || offset >= fText->Length()) return '\0'; - return (*fText)[offset]; + return fText->RealCharAt(offset); } @@ -1635,7 +1634,7 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const height = (line + 1)->origin - line->origin; // special case: go down one line if inOffset is a newline - if (inOffset == textLength && (*fText)[inOffset - 1] == B_ENTER) { + if (inOffset == textLength && fText->RealCharAt(inOffset - 1) == B_ENTER) { result.y += height; height = LineHeight(CountLines() - 1); @@ -1862,7 +1861,7 @@ BTextView::TextHeight(int32 startLine, int32 endLine) const float height = (*fLines)[endLine + 1]->origin - (*fLines)[startLine]->origin; - if (startLine != endLine && endLine == numLines - 1 && (*fText)[fText->Length() - 1] == B_ENTER) + if (startLine != endLine && endLine == numLines - 1 && fText->RealCharAt(fText->Length() - 1) == B_ENTER) height += (*fLines)[endLine + 1]->origin - (*fLines)[endLine]->origin; return ceilf(height); @@ -2652,7 +2651,7 @@ BTextView::GetDragParameters(BMessage *drag, BBitmap **bitmap, BPoint *point, BH drag->AddInt32("be_actions", B_TRASH_TARGET); // add the text - drag->AddData("text/plain", B_MIME_TYPE, fText->Text() + fSelStart, + drag->AddData("text/plain", B_MIME_TYPE, fText->RealText() + fSelStart, fSelEnd - fSelStart); // add the corresponding styles @@ -3287,7 +3286,7 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent, break; } for ( ; (offset + delta) < limit; delta++) { - uchar theChar = (*fText)[offset + delta]; + uchar theChar = fText->RealCharAt(offset + delta); if (!CanEndLine(offset + delta)) break; @@ -3320,7 +3319,7 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent, tabWidth = 0.0; else { int32 tabCount = 0; - for (int32 i = delta - 1; (*fText)[offset + i] == B_TAB; i--) + for (int32 i = delta - 1; fText->RealCharAt(offset + i) == B_TAB; i--) tabCount++; tabWidth = ActualTabWidth(strWidth); @@ -3350,12 +3349,13 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent, float *outDescent, if (!foundNewline) { for ( ; (offset + delta) < limit; delta++) { - if ((*fText)[offset + delta] != B_SPACE && - (*fText)[offset + delta] != B_TAB) + const char realChar = fText->RealCharAt(offset + delta); + if (realChar != B_SPACE + && realChar != B_TAB) break; } - if ( (offset + delta) < limit && - (*fText)[offset + delta] == B_ENTER ) + if ((offset + delta) < limit + && fText->RealCharAt(offset + delta) == B_ENTER ) delta++; } // get the ascent and descent of the spaces/tabs @@ -3426,7 +3426,7 @@ BTextView::StyledWidth(int32 fromOffset, int32 length, float *outAscent, UnlockWidthBuffer(); } else #endif - result += font->StringWidth(fText->Text() + fromOffset, numChars); + result += font->StringWidth(fText->RealText() + fromOffset, numChars); fromOffset += numChars; length -= numChars; @@ -3593,8 +3593,9 @@ BTextView::_DrawLine(BView *view, const int32 &lineNum, const int32 &startOffset } int32 returnedBytes = tabChars; - view->DrawString(fText->GetString(offset, &returnedBytes), returnedBytes); - + const char *stringToDraw = fText->GetString(offset, &returnedBytes); + + view->DrawString(stringToDraw, returnedBytes); if (foundTab) { float penPos = PenLocation().x - fTextRect.left; float tabWidth = ActualTabWidth(penPos); @@ -4308,6 +4309,13 @@ BTextView::GetProperty(BMessage *specifier, int32 form, const char *property, BM return true; } else if (strcmp(property, "Text") == 0) { + + if (IsTypingHidden()) { + // Do not allow stealing passwords via scripting + beep(); + return false; + } + int32 index, range; specifier->FindInt32("index", &index); diff --git a/src/kits/interface/textview_support/TextGapBuffer.cpp b/src/kits/interface/textview_support/TextGapBuffer.cpp index 2df8fe94f4..6fd200efcc 100644 --- a/src/kits/interface/textview_support/TextGapBuffer.cpp +++ b/src/kits/interface/textview_support/TextGapBuffer.cpp @@ -7,6 +7,7 @@ * Stefano Ceccherini (burton666@libero.it) */ +#include #include #include @@ -193,7 +194,7 @@ _BTextGapBuffer_::GetString(int32 fromOffset, int32 *_numBytes) } for (long i = 0; i < numBytes; i++) - fScratchBuffer[i] = (*this)[fromOffset + i]; + fScratchBuffer[i] = RealCharAt(fromOffset + i); result = fScratchBuffer; } @@ -203,7 +204,8 @@ _BTextGapBuffer_::GetString(int32 fromOffset, int32 *_numBytes) if (fPasswordMode) { uint32 numChars = UTF8CountChars(result, numBytes); uint32 charLen = UTF8CountBytes(B_UTF8_BULLET, 1); - uint32 newSize = numChars * charLen + 1; + uint32 newSize = numChars * charLen; + if ((uint32)fScratchSize < newSize) { fScratchBuffer = (char *)realloc(fScratchBuffer, newSize); fScratchSize = newSize; @@ -215,7 +217,6 @@ _BTextGapBuffer_::GetString(int32 fromOffset, int32 *_numBytes) memcpy(scratchPtr, B_UTF8_BULLET, charLen); scratchPtr += charLen; } - scratchPtr = '\0'; *_numBytes = newSize - 1; } @@ -228,9 +229,9 @@ _BTextGapBuffer_::FindChar(char inChar, long fromIndex, long *ioDelta) { long numChars = *ioDelta; for (long i = 0; i < numChars; i++) { - if (((*this)[fromIndex + i] & 0xc0) == 0x80) + if ((RealCharAt(fromIndex + i) & 0xc0) == 0x80) continue; - if ((*this)[fromIndex + i] == inChar) { + if (RealCharAt(fromIndex + i) == inChar) { *ioDelta = i; return true; } @@ -242,6 +243,35 @@ _BTextGapBuffer_::FindChar(char inChar, long fromIndex, long *ioDelta) const char * _BTextGapBuffer_::Text() +{ + const char *realText = RealText(); + + if (fPasswordMode) { + const uint32 numChars = UTF8CountChars(realText, Length()); + const uint32 bulletCharLen = UTF8CountBytes(B_UTF8_BULLET, 1); + uint32 newSize = numChars * bulletCharLen + 1; + + if ((uint32)fScratchSize < newSize) { + fScratchBuffer = (char *)realloc(fScratchBuffer, newSize); + fScratchSize = newSize; + } + + char *scratchPtr = fScratchBuffer; + for (uint32 i = 0; i < numChars; i++) { + memcpy(scratchPtr, B_UTF8_BULLET, bulletCharLen); + scratchPtr += bulletCharLen; + } + scratchPtr = '\0'; + + return fScratchBuffer; + } + + return realText; +} + + +const char * +_BTextGapBuffer_::RealText() { MoveGapTo(fItemCount); fBuffer[fItemCount] = '\0'; @@ -250,13 +280,6 @@ _BTextGapBuffer_::Text() } -/*char * -_BTextGapBuffer_::RealText() -{ - return fText; -}*/ - - void _BTextGapBuffer_::GetString(int32 offset, int32 length, char *buffer) { @@ -298,13 +321,6 @@ _BTextGapBuffer_::GetString(int32 offset, int32 length, char *buffer) } -char -_BTextGapBuffer_::RealCharAt(int32 offset) const -{ - return (offset < fGapIndex) ? fBuffer[offset] : fBuffer[offset + fGapCount]; -} - - bool _BTextGapBuffer_::PasswordMode() const { diff --git a/src/kits/interface/textview_support/TextGapBuffer.h b/src/kits/interface/textview_support/TextGapBuffer.h index 81a6f5e5e0..48eb44272a 100644 --- a/src/kits/interface/textview_support/TextGapBuffer.h +++ b/src/kits/interface/textview_support/TextGapBuffer.h @@ -29,11 +29,9 @@ virtual ~_BTextGapBuffer_(); bool FindChar(char inChar, int32 fromIndex, int32 *ioDelta); const char *Text(); + const char *RealText(); int32 Length() const; - char operator[](int32 index) const; - -// char *RealText(); const char *GetString(int32 fromOffset, int32 *numBytes); void GetString(int32 offset, int32 length, char *buffer); @@ -65,7 +63,7 @@ _BTextGapBuffer_::Length() const inline char -_BTextGapBuffer_::operator[](long index) const +_BTextGapBuffer_::RealCharAt(long index) const { return (index < fGapIndex) ? fBuffer[index] : fBuffer[index + fGapCount]; }