aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2026-04-23 10:42:27 +1000
committerNeil <nyamatongwe@gmail.com>2026-04-23 10:42:27 +1000
commitfc5004a9e14cfd5c462abca0c8af3cab614aa48d (patch)
tree3ee485eec59e9f1547002a8b862c3d25b2a7e306 /src
parentff16983250f077aa2fa1ac1039ad421813fd20f0 (diff)
downloadscintilla-mirror-fc5004a9e14cfd5c462abca0c8af3cab614aa48d.tar.gz
Add error status SC_STATUS_OUTSIDE_DOCUMENT that is set when operations are
attempted on a position outside the document. Positions are checked earlier to prevent actions partly succeeding. This is implemented with a new exception type Failure which should be caught by platform layer's API handling code to produce a more granular error status.
Diffstat (limited to 'src')
-rw-r--r--src/CellBuffer.h5
-rw-r--r--src/Document.cxx9
-rw-r--r--src/Document.h1
-rw-r--r--src/Editor.cxx3
4 files changed, 17 insertions, 1 deletions
diff --git a/src/CellBuffer.h b/src/CellBuffer.h
index d54d2be8d..11479f14a 100644
--- a/src/CellBuffer.h
+++ b/src/CellBuffer.h
@@ -10,6 +10,11 @@
namespace Scintilla::Internal {
+struct Failure : public std::runtime_error {
+ Status status;
+ Failure(Status status_) : std::runtime_error("failure with status"), status(status_) {}
+};
+
// Interface to per-line data that wants to see each line insertion and deletion
class PerLine {
public:
diff --git a/src/Document.cxx b/src/Document.cxx
index f3dac9aaa..289fb6731 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -530,6 +530,13 @@ void SCI_METHOD Document::SetErrorStatus(int status) {
}
}
+void Document::CheckPosition(Sci::Position pos) const {
+ PLATFORM_ASSERT((pos >= 0) && (pos <= LengthNoExcept()));
+ if ((pos < 0) || (pos > LengthNoExcept())) {
+ throw Failure(Status::OutsideDocument);
+ }
+}
+
Sci_Position SCI_METHOD Document::LineFromPosition(Sci_Position pos) const {
return cb.LineFromPosition(pos);
}
@@ -1485,7 +1492,7 @@ Sci::Position Document::InsertString(Sci::Position position, const char *s, Sci:
if (insertLength <= 0) {
return 0;
}
- PLATFORM_ASSERT((position >= 0) && (position <= Length()));
+ CheckPosition(position);
CheckReadOnly(); // Application may change read only state here
if (cb.IsReadOnly()) {
return 0;
diff --git a/src/Document.h b/src/Document.h
index 7fd150f37..dfb0a7ff5 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -369,6 +369,7 @@ public:
int SCI_METHOD DEVersion() const noexcept override;
void SCI_METHOD SetErrorStatus(int status) override;
+ void CheckPosition(Sci::Position pos) const;
Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const override;
Sci::Line SciLineFromPosition(Sci::Position pos) const noexcept; // Avoids casting LineFromPosition
diff --git a/src/Editor.cxx b/src/Editor.cxx
index d946c7bd2..1dfa8fd6b 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -5899,6 +5899,8 @@ Sci::Position Editor::GetTag(char *tagValue, int tagNumber) {
}
Sci::Position Editor::ReplaceTarget(ReplaceType replaceType, std::string_view text) {
+ pdoc->CheckPosition(targetRange.start.Position());
+
UndoGroup ug(pdoc);
std::string substituted; // Copy in case of re-entrance
@@ -6697,6 +6699,7 @@ sptr_t Editor::WndProc(Message iMessage, uptr_t wParam, sptr_t lParam) {
Sci::Position insertPos = PositionFromUPtr(wParam);
if (insertPos == -1)
insertPos = CurrentPosition();
+ pdoc->CheckPosition(insertPos);
Sci::Position newCurrent = CurrentPosition();
const char *sz = ConstCharPtrFromSPtr(lParam);
const Sci::Position lengthInserted = pdoc->InsertString(insertPos, sz, strlen(sz));