forked from qt-creator/qt-creator
Lua: Secure TextEditor access
Since the script can get the currentEditor which may be destroyed without the script noticing, we use QPointer<> instead to safe-guard access. Change-Id: I5d1943323297bdff87d6946751dc8f8dd80ccad0 Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -396,6 +396,9 @@ void addFloatingWidget(TextEditor::BaseTextEditor *editor, QWidget *widget, int
|
|||||||
|
|
||||||
namespace Lua::Internal {
|
namespace Lua::Internal {
|
||||||
|
|
||||||
|
using TextEditorPtr = QPointer<TextEditor::BaseTextEditor>;
|
||||||
|
using TextDocumentPtr = QPointer<TextEditor::TextDocument>;
|
||||||
|
|
||||||
class TextEditorRegistry : public QObject
|
class TextEditorRegistry : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -474,7 +477,7 @@ signals:
|
|||||||
void currentCursorChanged(TextEditor::BaseTextEditor *editor, MultiTextCursor cursor);
|
void currentCursorChanged(TextEditor::BaseTextEditor *editor, MultiTextCursor cursor);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QPointer<TextEditor::BaseTextEditor> m_currentTextEditor = nullptr;
|
TextEditorPtr m_currentTextEditor = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setupTextEditorModule()
|
void setupTextEditorModule()
|
||||||
@@ -484,7 +487,7 @@ void setupTextEditorModule()
|
|||||||
registerProvider("TextEditor", [](sol::state_view lua) -> sol::object {
|
registerProvider("TextEditor", [](sol::state_view lua) -> sol::object {
|
||||||
sol::table result = lua.create_table();
|
sol::table result = lua.create_table();
|
||||||
|
|
||||||
result["currentEditor"] = []() -> TextEditor::BaseTextEditor * {
|
result["currentEditor"] = []() -> TextEditorPtr {
|
||||||
return TextEditor::BaseTextEditor::currentTextEditor();
|
return TextEditor::BaseTextEditor::currentTextEditor();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -531,20 +534,27 @@ void setupTextEditorModule()
|
|||||||
"TextEditor",
|
"TextEditor",
|
||||||
sol::no_constructor,
|
sol::no_constructor,
|
||||||
"document",
|
"document",
|
||||||
&TextEditor::BaseTextEditor::textDocument,
|
[](const TextEditorPtr &textEditor) -> TextDocumentPtr {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
|
return textEditor->textDocument();
|
||||||
|
},
|
||||||
"addFloatingWidget",
|
"addFloatingWidget",
|
||||||
sol::overload(
|
sol::overload(
|
||||||
[](TextEditor::BaseTextEditor *textEditor, QWidget *widget, int position) {
|
[](const TextEditorPtr &textEditor, QWidget *widget, int position) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
addFloatingWidget(textEditor, widget, position);
|
addFloatingWidget(textEditor, widget, position);
|
||||||
},
|
},
|
||||||
[](TextEditor::BaseTextEditor *textEditor, Layouting::Widget *widget, int position) {
|
[](const TextEditorPtr &textEditor, Layouting::Widget *widget, int position) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
addFloatingWidget(textEditor, widget->emerge(), position);
|
addFloatingWidget(textEditor, widget->emerge(), position);
|
||||||
},
|
},
|
||||||
[](TextEditor::BaseTextEditor *textEditor, Layouting::Layout *layout, int position) {
|
[](const TextEditorPtr &textEditor, Layouting::Layout *layout, int position) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
addFloatingWidget(textEditor, layout->emerge(), position);
|
addFloatingWidget(textEditor, layout->emerge(), position);
|
||||||
}),
|
}),
|
||||||
"cursor",
|
"cursor",
|
||||||
[](TextEditor::BaseTextEditor *textEditor) {
|
[](const TextEditorPtr &textEditor) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
return textEditor->editorWidget()->multiTextCursor();
|
return textEditor->editorWidget()->multiTextCursor();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -566,10 +576,14 @@ void setupTextEditorModule()
|
|||||||
"TextDocument",
|
"TextDocument",
|
||||||
sol::no_constructor,
|
sol::no_constructor,
|
||||||
"file",
|
"file",
|
||||||
&TextEditor::TextDocument::filePath,
|
[](const TextDocumentPtr &document) {
|
||||||
|
QTC_ASSERT(document, throw sol::error("TextDocument is not valid"));
|
||||||
|
return document->filePath();
|
||||||
|
},
|
||||||
"blockAndColumn",
|
"blockAndColumn",
|
||||||
[](TextEditor::TextDocument *document,
|
[](const TextDocumentPtr &document,
|
||||||
int position) -> std::optional<std::pair<int, int>> {
|
int position) -> std::optional<std::pair<int, int>> {
|
||||||
|
QTC_ASSERT(document, throw sol::error("TextDocument is not valid"));
|
||||||
QTextBlock block = document->document()->findBlock(position);
|
QTextBlock block = document->document()->findBlock(position);
|
||||||
if (!block.isValid())
|
if (!block.isValid())
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@@ -579,9 +593,14 @@ void setupTextEditorModule()
|
|||||||
return std::make_pair(block.blockNumber() + 1, column + 1);
|
return std::make_pair(block.blockNumber() + 1, column + 1);
|
||||||
},
|
},
|
||||||
"blockCount",
|
"blockCount",
|
||||||
[](TextEditor::TextDocument *document) { return document->document()->blockCount(); },
|
[](const TextDocumentPtr &document) {
|
||||||
|
QTC_ASSERT(document, throw sol::error("TextDocument is not valid"));
|
||||||
|
return document->document()->blockCount();
|
||||||
|
},
|
||||||
"setSuggestions",
|
"setSuggestions",
|
||||||
[](TextEditor::TextDocument *document, QList<Suggestion> suggestions) {
|
[](const TextDocumentPtr &document, QList<Suggestion> suggestions) {
|
||||||
|
QTC_ASSERT(document, throw sol::error("TextDocument is not valid"));
|
||||||
|
|
||||||
if (suggestions.isEmpty())
|
if (suggestions.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
#include <QPointer>
|
||||||
#include <QRect>
|
#include <QRect>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
@@ -37,3 +38,17 @@ SOL_CONVERSION_FUNCTIONS(QColor)
|
|||||||
SOL_CONVERSION_FUNCTIONS(QStringList)
|
SOL_CONVERSION_FUNCTIONS(QStringList)
|
||||||
|
|
||||||
#undef SOL_CONVERSION_FUNCTIONS
|
#undef SOL_CONVERSION_FUNCTIONS
|
||||||
|
|
||||||
|
namespace sol {
|
||||||
|
template<typename T>
|
||||||
|
struct unique_usertype_traits<QPointer<T>>
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
typedef QPointer<T> actual_type;
|
||||||
|
static const bool value = true;
|
||||||
|
|
||||||
|
static bool is_null(const actual_type &ptr) { return ptr == nullptr; }
|
||||||
|
|
||||||
|
static type *get(const actual_type &ptr) { return ptr.get(); }
|
||||||
|
};
|
||||||
|
} // namespace sol
|
||||||
|
Reference in New Issue
Block a user