Skip to content

Commit 5cb743f

Browse files
committed
fix: capture bad_alloc
Refactor file read error handling into separate method. Add exception handling for memory allocation errors. Log: fix a memory issue. Bug: https://pms.uniontech.com/bug-view-311693.html
1 parent 7edacc5 commit 5cb743f

2 files changed

Lines changed: 63 additions & 47 deletions

File tree

src/editor/editwrapper.cpp

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -900,15 +900,7 @@ void EditWrapper::handleFileLoadFinished(const QByteArray &encode, const QByteAr
900900

901901
// 提示读取错误信息
902902
if (error) {
903-
// 设置文本为只读模式,且不显示通知
904-
if (!m_pTextEdit->getReadOnlyMode()) {
905-
m_pTextEdit->toggleReadOnlyMode(true);
906-
}
907-
908-
m_pWaringNotices->setMessage(tr("The file cannot be read, which may be too large or has been damaged!"));
909-
m_pWaringNotices->clearBtn();
910-
m_pWaringNotices->show();
911-
DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices);
903+
onReadAllocError();
912904
}
913905
}
914906

@@ -1166,52 +1158,61 @@ void EditWrapper::customEvent(QEvent *e)
11661158
return;
11671159
}
11681160

1169-
ParseFileEvent *parseEvent = static_cast<ParseFileEvent *>(e);
1170-
int needReadLen = parseEvent->m_contentData.length() - parseEvent->m_alreadyReadOffset;
1161+
bool errorOccurred = false;
1162+
try {
11711163

1172-
// 调整最大读取长度(单次读取最大长度)
1173-
if (needReadLen > EReadStepSize) {
1174-
needReadLen = EReadStepSize;
1175-
}
1164+
ParseFileEvent *parseEvent = static_cast<ParseFileEvent *>(e);
1165+
int needReadLen = parseEvent->m_contentData.length() - parseEvent->m_alreadyReadOffset;
11761166

1177-
// 转码数据并插入光标位置
1178-
QByteArray text = parseEvent->m_contentData.mid(parseEvent->m_alreadyReadOffset, needReadLen);
1179-
QTextCodec::ConverterState state;
1180-
QString data = parseEvent->m_codec->toUnicode(text.constData(), text.size(), &state);
1167+
// 调整最大读取长度(单次读取最大长度)
1168+
if (needReadLen > EReadStepSize) {
1169+
needReadLen = EReadStepSize;
1170+
}
11811171

1182-
// TODO: Qt5 just under 2^30 characters in one QString.
1183-
// In Qt6.8, the value up to almost 2^63, release on Qt6.
1184-
try {
1172+
// 转码数据并插入光标位置
1173+
QByteArray text = parseEvent->m_contentData.mid(parseEvent->m_alreadyReadOffset, needReadLen);
1174+
QTextCodec::ConverterState state;
1175+
QString data = parseEvent->m_codec->toUnicode(text.constData(), text.size(), &state);
1176+
1177+
// Note: Qt5 just under 2^30 characters (almost 1GB) in one QString.
1178+
// In Qt6.8, the value up to almost 2^63, release on Qt6.
11851179
parseEvent->m_cursor.insertText(data);
1186-
} catch (std::exception &e) {
1187-
qCritical() << "Insert file data error" << e.what();
1188-
// read abort!
1189-
m_bAsyncReadFileFinished = true;
1190-
return;
1191-
}
11921180

1193-
// 当前为首次读取
1194-
if (0 == parseEvent->m_alreadyReadOffset) {
1195-
QTextCursor firstLineCursor = m_pTextEdit->textCursor();
1196-
firstLineCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
1197-
m_pTextEdit->setTextCursor(firstLineCursor);
1198-
//秒开界面语法高亮
1199-
OnUpdateHighlighter();
1200-
}
1181+
// 当前为首次读取
1182+
if (0 == parseEvent->m_alreadyReadOffset) {
1183+
QTextCursor firstLineCursor = m_pTextEdit->textCursor();
1184+
firstLineCursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
1185+
m_pTextEdit->setTextCursor(firstLineCursor);
1186+
//秒开界面语法高亮
1187+
OnUpdateHighlighter();
1188+
}
1189+
1190+
// 此次读取后的偏移量
1191+
int curReadOffset = parseEvent->m_alreadyReadOffset + needReadLen;
1192+
1193+
// 是否已读取完成
1194+
if (parseEvent->m_contentData.length() == curReadOffset) {
1195+
// 异步读取结束
1196+
m_bAsyncReadFileFinished = true;
1197+
} else {
1198+
ParseFileEvent *nextEvent = parseEvent->clone();
1199+
// 调整已读取偏移位置
1200+
nextEvent->m_alreadyReadOffset = curReadOffset;
1201+
// 抛出下一次处理的事件,根据当前是否显示界面调整优先级
1202+
qApp->postEvent(this, nextEvent, isVisible() ? Qt::NormalEventPriority : (Qt::LowEventPriority - 1));
1203+
}
12011204

1202-
// 此次读取后的偏移量
1203-
int curReadOffset = parseEvent->m_alreadyReadOffset + needReadLen;
1205+
} catch (const std::bad_alloc &) {
1206+
errorOccurred = true;
1207+
qWarning() << "Memory allocation failed";
1208+
} catch (const std::exception &e) {
1209+
errorOccurred = true;
1210+
qWarning() << QString("Error occurred: %1").arg(e.what());
1211+
}
12041212

1205-
// 是否已读取完成
1206-
if (parseEvent->m_contentData.length() == curReadOffset) {
1207-
// 异步读取结束
1213+
if (errorOccurred) {
12081214
m_bAsyncReadFileFinished = true;
1209-
} else {
1210-
ParseFileEvent *nextEvent = parseEvent->clone();
1211-
// 调整已读取偏移位置
1212-
nextEvent->m_alreadyReadOffset = curReadOffset;
1213-
// 抛出下一次处理的事件,根据当前是否显示界面调整优先级
1214-
qApp->postEvent(this, nextEvent, isVisible() ? Qt::NormalEventPriority : (Qt::LowEventPriority - 1));
1215+
QMetaObject::invokeMethod(this, &EditWrapper::onReadAllocError, Qt::QueuedConnection);
12151216
}
12161217
}
12171218
}
@@ -1367,6 +1368,19 @@ void EditWrapper::reinitOnFileLoad(const QByteArray &encode)
13671368
m_sFirstEncode = encode;
13681369
}
13691370

1371+
void EditWrapper::onReadAllocError()
1372+
{
1373+
// 设置文本为只读模式,且不显示通知
1374+
if (!m_pTextEdit->getReadOnlyMode()) {
1375+
m_pTextEdit->toggleReadOnlyMode(true);
1376+
}
1377+
1378+
m_pWaringNotices->setMessage(tr("The file cannot be read, which may be too large or has been damaged!"));
1379+
m_pWaringNotices->clearBtn();
1380+
m_pWaringNotices->show();
1381+
DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices);
1382+
}
1383+
13701384
void EditWrapper::clearDoubleCharaterEncode()
13711385
{
13721386
if (QFileInfo(filePath()).baseName().contains("double")

src/editor/editwrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class EditWrapper : public QWidget
134134
// 文件加载时重新初始化部分设置
135135
void reinitOnFileLoad(const QByteArray &encode);
136136

137+
Q_SLOT void onReadAllocError();
138+
137139
public slots:
138140
// 处理文档预加载数据
139141
void handleFilePreProcess(const QByteArray &encode, const QByteArray &content);

0 commit comments

Comments
 (0)