From fc5004a9e14cfd5c462abca0c8af3cab614aa48d Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 23 Apr 2026 10:42:27 +1000 Subject: 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. --- src/CellBuffer.h | 5 +++++ src/Document.cxx | 9 ++++++++- src/Document.h | 1 + src/Editor.cxx | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-) (limited to 'src') 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)); -- cgit v1.2.3