Skip to content

Commit

Permalink
fix: [crash] App crashed when renaming files with special character sets
Browse files Browse the repository at this point in the history
The length of some special characters is 2, causing the cursor to be incorrectly calculated

Log: fix bug
Bug: https://pms.uniontech.com/bug-view-211431.html
  • Loading branch information
Kakueeen authored and deepin-bot[bot] committed Jul 25, 2023
1 parent bc12e2d commit 34e23aa
Show file tree
Hide file tree
Showing 14 changed files with 35 additions and 166 deletions.
28 changes: 28 additions & 0 deletions src/dfm-base/utils/fileutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,34 @@ QString FileUtils::preprocessingFileName(QString name)
return name.remove(QRegularExpression(value));
}

bool FileUtils::processLength(const QString &srcText, int srcPos, int maxLen, bool useCharCount, QString &dstText, int &dstPos)
{
auto textLength = [&](const QString &text) {
return useCharCount ? text.length() : text.toLocal8Bit().length();
};

int editTextCurrLen = textLength(srcText);
int editTextRangeOutLen = editTextCurrLen - maxLen;
if (editTextRangeOutLen > 0 && maxLen != INT_MAX) {
QString leftText = srcText.left(srcPos);
QString rightText = srcText.mid(srcPos);

while (textLength(leftText + rightText) > maxLen) {
auto list = leftText.toUcs4();
list.removeLast();
leftText = QString::fromUcs4(list.data(), list.size());
}

dstPos = leftText.size();
dstText = leftText + rightText;
return srcText.size() != dstText.size();
} else {
dstText = srcText;
dstPos = srcPos;
return false;
}
}

bool FileUtils::isContainProhibitPath(const QList<QUrl> &urls)
{
QStringList prohibitPaths;
Expand Down
1 change: 1 addition & 0 deletions src/dfm-base/utils/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class FileUtils
static bool isMtpFile(const QUrl &url);
static bool isGphotoFile(const QUrl &url);
static QString preprocessingFileName(QString name);
static bool processLength(const QString &srcText, int srcPos, int maxLen, bool useCharCount, QString &dstText, int &dstPos);
static bool isContainProhibitPath(const QList<QUrl> &urls);

// check if is trash/computer desktop file containing Deepin_id of dde-trash/dde-computer
Expand Down
23 changes: 1 addition & 22 deletions src/plugins/desktop/core/ddplugin-canvas/delegate/itemeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,27 +213,6 @@ RenameEdit *ItemEditor::createEditor()
return edit;
}

bool ItemEditor::processLength(const QString &srcText, int srcPos, QString &dstText, int &dstPos)
{
int editTextCurrLen = textLength(srcText);
int editTextRangeOutLen = editTextCurrLen - maximumLength();
if (editTextRangeOutLen > 0 && maximumLength() != INT_MAX) {
QVector<uint> list = srcText.toUcs4();
QString tmp = srcText;
while (textLength(tmp) > maximumLength() && srcPos > 0) {
list.removeAt(--srcPos);
tmp = QString::fromUcs4(list.data(), list.size());
}
dstText = tmp;
dstPos = srcPos;
return srcText.size() != dstText.size();
} else {
dstText = srcText;
dstPos = srcPos;
return false;
}
}

void ItemEditor::textChanged()
{
if (sender() != textEditor)
Expand All @@ -257,7 +236,7 @@ void ItemEditor::textChanged()
bool hasInvalidChar = dstText.size() != curText.size();
int endPos = textEditor->textCursor().position() + (dstText.length() - curText.length());

processLength(dstText, endPos, dstText, endPos);
DFMBASE_NAMESPACE::FileUtils::processLength(dstText, endPos, maximumLength(), useCharCount, dstText, endPos);
if (curText != dstText) {
textEditor->setPlainText(dstText);
QTextCursor cursor = textEditor->textCursor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ public slots:
protected:
static RenameEdit *createEditor();
static DTK_WIDGET_NAMESPACE::DArrowRectangle *createTooltip();
bool processLength(const QString &srcText, int srcPos, QString &dstText, int &dstPos);
inline int textLength(const QString &text)
{
return useCharCount ? text.length() : text.toLocal8Bit().length();
}
private slots:
void textChanged();

Expand Down
23 changes: 1 addition & 22 deletions src/plugins/desktop/ddplugin-organizer/delegate/itemeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,27 +213,6 @@ RenameEdit *ItemEditor::createEditor()
return edit;
}

bool ItemEditor::processLength(const QString &srcText, int srcPos, QString &dstText, int &dstPos)
{
int editTextCurrLen = textLength(srcText);
int editTextRangeOutLen = editTextCurrLen - maximumLength();
if (editTextRangeOutLen > 0 && maximumLength() != INT_MAX) {
QVector<uint> list = srcText.toUcs4();
QString tmp = srcText;
while (textLength(tmp) > maximumLength() && srcPos > 0) {
list.removeAt(--srcPos);
tmp = QString::fromUcs4(list.data(), list.size());
}
dstText = tmp;
dstPos = srcPos;
return srcText.size() != dstText.size();
} else {
dstText = srcText;
dstPos = srcPos;
return false;
}
}

void ItemEditor::textChanged()
{
if (sender() != textEditor)
Expand All @@ -257,7 +236,7 @@ void ItemEditor::textChanged()
bool hasInvalidChar = dstText.size() != curText.size();
int endPos = textEditor->textCursor().position() + (dstText.length() - curText.length());

processLength(dstText, endPos, dstText, endPos);
DFMBASE_NAMESPACE::FileUtils::processLength(dstText, endPos, maximumLength(), useCharCount, dstText, endPos);
if (curText != dstText) {
textEditor->setPlainText(dstText);
QTextCursor cursor = textEditor->textCursor();
Expand Down
5 changes: 0 additions & 5 deletions src/plugins/desktop/ddplugin-organizer/delegate/itemeditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,6 @@ public slots:
protected:
static RenameEdit *createEditor();
static DTK_WIDGET_NAMESPACE::DArrowRectangle *createTooltip();
bool processLength(const QString &srcText, int srcPos, QString &dstText, int &dstPos);
inline int textLength(const QString &text)
{
return useCharCount ? text.length() : text.toLocal8Bit().length();
}
private slots:
void textChanged();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,25 +329,22 @@ void SideBarItemDelegate::onEditorTextChanged(const QString &text, const FileInf
return;

int maxLen = INT_MAX;
int textLen = 0;
bool useCharCount = false;
const QString &fs = info->extraProperties()[GlobalServerDefines::DeviceProperty::kFileSystem].toString();
if (fs.isEmpty()) {
const auto &url = info->urlOf(FileInfo::FileUrlInfoType::kUrl);
if (FileUtils::isLocalFile(url)) {
maxLen = NAME_MAX;
const auto &path = url.path();
useCharCount = DeviceUtils::isSubpathOfDlnfs(path);
textLen = textLength(text, path.isEmpty() ? false : useCharCount);
useCharCount = path.isEmpty() ? false : DeviceUtils::isSubpathOfDlnfs(path);
}
} else {
maxLen = FileUtils::supportedMaxLength(fs);
textLen = textLength(text, false);
}

QString dstText = text;
int currPos = editor->cursorPosition();
processLength(maxLen, textLen, useCharCount, dstText, currPos);
FileUtils::processLength(dstText, currPos, maxLen, useCharCount, dstText, currPos);

if (text != dstText) {
QSignalBlocker blocker(editor);
Expand Down Expand Up @@ -433,26 +430,3 @@ void SideBarItemDelegate::drawMouseHoverExpandButton(QPainter *painter, const QR
icon.paint(painter, QRect(gRect.topLeft() + QPoint(2, 3), QSize(iconSize, iconSize)), Qt::AlignmentFlag::AlignCenter);
painter->restore();
}

int SideBarItemDelegate::textLength(const QString &text, bool useCharCount) const
{
return useCharCount ? text.size() : text.toLocal8Bit().size();
}

void SideBarItemDelegate::processLength(int maxLen, int textLen, bool useCharCount, QString &text, int &pos) const
{
QString srcText = text;
int srcPos = pos;
int editTextRangeOutLen = textLen - maxLen;
if (editTextRangeOutLen > 0 && maxLen != INT_MAX) {
QVector<uint> list = srcText.toUcs4();
QString tmp = srcText;
while (textLength(tmp, useCharCount) > maxLen && srcPos > 0) {
list.removeAt(--srcPos);
tmp = QString::fromUcs4(list.data(), list.size());
}

text = tmp;
pos = srcPos;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ public Q_SLOTS:
void drawIcon(const QStyleOptionViewItem &option, QPainter *painter, const QIcon &icon, const QRect &itemRect, QIcon::Mode iconMode, bool isEjectable) const;
void drawMouseHoverBackground(QPainter *painter, const DPalette &palette, const QRect &r, const QColor &widgetColor) const;
void drawMouseHoverExpandButton(QPainter *painter, const QRect &r, bool isExpanded) const;
int textLength(const QString &text, bool useCharCount) const;
void processLength(int maxLen, int textLen, bool useCharCount, QString &text, int &pos) const;

Q_SIGNALS:
void rename(const QModelIndex &index, QString newName) const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,7 @@ void IconItemEditor::onEditTextChanged()

int endPos = getTextEdit()->textCursor().position() + (dstText.length() - currentText.length());

processLength(dstText, endPos);

FileUtils::processLength(dstText, endPos, maxCharSize(), d->useCharCountLimit, dstText, endPos);
if (currentText != dstText) {
d->edit->setPlainText(dstText);
QTextCursor cursor = d->edit->textCursor();
Expand Down Expand Up @@ -435,28 +434,3 @@ DArrowRectangle *IconItemEditor::createTooltip()
return tooltip;
}

bool IconItemEditor::processLength(QString &text, int &pos)
{
const QString srcText = text;
int srcPos = pos;
int editTextCurrLen = textLength(srcText);
int editTextRangeOutLen = editTextCurrLen - maxCharSize();
if (editTextRangeOutLen > 0 && maxCharSize() != INT_MAX) {
QVector<uint> list = srcText.toUcs4();
QString tmp = srcText;
while (textLength(tmp) > maxCharSize() && srcPos > 0) {
list.removeAt(--srcPos);
tmp = QString::fromUcs4(list.data(), list.size());
}
text = tmp;
pos = srcPos;
return srcText.size() != text.size();
}
return false;
}

int IconItemEditor::textLength(const QString &text)
{
Q_D(IconItemEditor);
return d->useCharCountLimit ? text.size() : text.toLocal8Bit().size();
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ private slots:
QString editTextStackAdvance();
void pushItemToEditTextStack(const QString &item);
static DTK_WIDGET_NAMESPACE::DArrowRectangle *createTooltip();
bool processLength(QString &text, int &pos);
int textLength(const QString &text);

friend class IconItemDelegate;
friend class FileView;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ void ListItemEditor::onEditorTextChanged(const QString &text)
int currPos = this->cursorPosition();
currPos += dstText.length() - text.length();

processLength(dstText, currPos);

FileUtils::processLength(dstText, currPos, theMaxCharSize, useCharCount, dstText, currPos);
if (srcText != dstText) {
QSignalBlocker blocker(this);
this->setText(dstText);
Expand All @@ -126,28 +125,3 @@ void ListItemEditor::init()
setContentsMargins(0, 0, 0, 0);
connect(this, &ListItemEditor::textChanged, this, &ListItemEditor::onEditorTextChanged, Qt::UniqueConnection);
}

bool ListItemEditor::processLength(QString &text, int &pos)
{
QString srcText = text;
int srcPos = pos;
int editTextCurrLen = textLength(srcText);
int editTextRangeOutLen = editTextCurrLen - theMaxCharSize;
if (editTextRangeOutLen > 0 && theMaxCharSize != INT_MAX) {
QVector<uint> list = srcText.toUcs4();
QString tmp = srcText;
while (textLength(tmp) > theMaxCharSize && srcPos > 0) {
list.removeAt(--srcPos);
tmp = QString::fromUcs4(list.data(), list.size());
}
text = tmp;
pos = srcPos;
return srcText.size() != text.size();
}
return false;
}

int ListItemEditor::textLength(const QString &text)
{
return useCharCount ? text.size() : text.toLocal8Bit().size();
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ private slots:

private:
void init();
bool processLength(QString &text, int &pos);
int textLength(const QString &text);

private:
int theMaxCharSize { INT_MAX };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,6 @@ TEST(ItemEditor, maximumLength)
EXPECT_EQ(ie.maximumLength(), 14);
}

TEST(ItemEditor, textLength)
{
ItemEditor ie;
const QString &text= "ni测试";
ie.useCharCount = false;
EXPECT_EQ(ie.textLength(text), 8);

ie.setCharCountLimit();
EXPECT_TRUE(ie.useCharCount);
EXPECT_EQ(ie.textLength(text), 4);
}

TEST(ItemEditor, setBaseGeometry)
{
ItemEditor ie;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,6 @@ TEST(ItemEditor, maximumLength)
EXPECT_EQ(ie.maximumLength(), 14);
}

TEST(ItemEditor, textLength)
{
ItemEditor ie;
const QString &text= "ni测试";
ie.useCharCount = false;
EXPECT_EQ(ie.textLength(text), 8);

ie.setCharCountLimit();
EXPECT_TRUE(ie.useCharCount);
EXPECT_EQ(ie.textLength(text), 4);
}

TEST(ItemEditor, setBaseGeometry)
{
ItemEditor ie;
Expand Down

0 comments on commit 34e23aa

Please sign in to comment.