diff options
author | nyamatongwe <devnull@localhost> | 2007-10-10 11:30:14 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2007-10-10 11:30:14 +0000 |
commit | f8453890acd38f68249965fe05a4392b69b986e5 (patch) | |
tree | fdbdb1340f059a882a4bdf3b0f734b8b72793ebb /src/PositionCache.cxx | |
parent | a71097b447b0391764c104f60d2bf52782e3ada7 (diff) | |
download | scintilla-mirror-f8453890acd38f68249965fe05a4392b69b986e5.tar.gz |
Detect and handle invalid byte sequences in UTF-8 mode by displaying each
individual invalid byte as a hex blob.
Diffstat (limited to 'src/PositionCache.cxx')
-rw-r--r-- | src/PositionCache.cxx | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/src/PositionCache.cxx b/src/PositionCache.cxx index 1763b6530..f40a15378 100644 --- a/src/PositionCache.cxx +++ b/src/PositionCache.cxx @@ -345,12 +345,23 @@ void LineLayoutCache::Dispose(LineLayout *ll) { } void BreakFinder::Insert(int val) { + // Expand if needed + if (saeLen >= saeSize) { + saeSize *= 2; + int *selAndEdgeNew = new int[saeSize]; + for (unsigned int j = 0; j<saeLen; j++) { + selAndEdgeNew[j] = selAndEdge[j]; + } + delete []selAndEdge; + selAndEdge = selAndEdgeNew; + } + if (val >= nextBreak) { for (unsigned int j = 0; j<saeLen; j++) { if (val == selAndEdge[j]) { return; } if (val < selAndEdge[j]) { - for (unsigned int k = saeLen; j>k; k--) { + for (unsigned int k = saeLen; k>j; k--) { selAndEdge[k] = selAndEdge[k-1]; } saeLen++; @@ -363,17 +374,32 @@ void BreakFinder::Insert(int val) { } } -BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, int xStart) : +extern bool BadUTF(const char *s, int len, int &trailBytes); + +static int NextBadU(const char *s, int p, int len, int &trailBytes) { + while (p < len) { + p++; + if (BadUTF(s + p, len - p, trailBytes)) + return p; + } + return -1; +} + +BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart) : ll(ll_), lineStart(lineStart_), lineEnd(lineEnd_), posLineStart(posLineStart_), + utf8(utf8_), nextBreak(lineStart_), + saeSize(0), saeLen(0), saeCurrentPos(0), saeNext(0), subBreak(-1) { - for (unsigned int j=0; j < sizeof(selAndEdge) / sizeof(selAndEdge[0]); j++) { + saeSize = 8; + selAndEdge = new int[saeSize]; + for (unsigned int j=0; j < saeSize; j++) { selAndEdge[j] = 0; } @@ -392,9 +418,24 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL Insert(ll->edgeColumn - 1); Insert(lineEnd - 1); + + if (utf8) { + int trailBytes=0; + for (int pos = -1;;) { + pos = NextBadU(ll->chars, pos, lineEnd, trailBytes); + if (pos < 0) + break; + Insert(pos-1); + Insert(pos); + } + } saeNext = (saeLen > 0) ? selAndEdge[0] : -1; } +BreakFinder::~BreakFinder() { + delete []selAndEdge; +} + int BreakFinder::First() { return nextBreak; } |