diff options
-rw-r--r-- | generic/tkText.h | 2 | ||||
-rw-r--r-- | generic/tkTextImage.c | 23 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 70 | ||||
-rw-r--r-- | generic/tkTextMark.c | 23 | ||||
-rw-r--r-- | generic/tkTextWind.c | 23 | ||||
-rw-r--r-- | tests/textIndex.test | 37 | ||||
-rw-r--r-- | tests/textMark.test | 11 |
7 files changed, 155 insertions, 34 deletions
diff --git a/generic/tkText.h b/generic/tkText.h index e9e6303..faa6014 100644 --- a/generic/tkText.h +++ b/generic/tkText.h @@ -1170,6 +1170,8 @@ MODULE_SCOPE int TkTextYviewCmd(TkText *textPtr, Tcl_Interp *interp, MODULE_SCOPE void TkTextWinFreeClient(Tcl_HashEntry *hPtr, TkTextEmbWindowClient *client); MODULE_SCOPE void TkTextRunAfterSyncCmd(ClientData clientData); +MODULE_SCOPE int TkTextIndexAdjustToStartEnd(TkText *textPtr, + TkTextIndex *indexPtr, int err); #endif /* _TKTEXT */ /* diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c index aeb5681..c5a7c84 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.c @@ -769,9 +769,9 @@ EmbImageBboxProc( * index corresponding to the image's position in the text. * * Results: - * The return value is 1 if there is an embedded image by the given name - * in the text widget, 0 otherwise. If the image exists, *indexPtr is - * filled in with its index. + * The return value is TCL_OK if there is an embedded image by the given + * name in the text widget, TCL_ERROR otherwise. If the image exists, + * *indexPtr is filled in with its index. * * Side effects: * None. @@ -789,18 +789,29 @@ TkTextImageIndex( TkTextSegment *eiPtr; if (textPtr == NULL) { - return 0; + return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->imageTable, name); if (hPtr == NULL) { - return 0; + return TCL_ERROR; } eiPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->sharedTextPtr->tree; indexPtr->linePtr = eiPtr->body.ei.linePtr; indexPtr->byteIndex = TkTextSegToOffset(eiPtr, indexPtr->linePtr); - return 1; + + /* + * If indexPtr refers to somewhere outside the -startline/-endline + * range limits of the widget, error out since the image indeed is not + * reachable from this text widget (it may be reachable from a peer). + */ + + if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) { + return TCL_ERROR; + } + + return TCL_OK; } /* diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index ade889b..bd93258 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -761,11 +761,11 @@ GetIndex( goto done; } - if (TkTextWindowIndex(textPtr, string, indexPtr) != 0) { + if (TkTextWindowIndex(textPtr, string, indexPtr) == TCL_OK) { goto done; } - if (TkTextImageIndex(textPtr, string, indexPtr) != 0) { + if (TkTextImageIndex(textPtr, string, indexPtr) == TCL_OK) { goto done; } @@ -917,7 +917,7 @@ GetIndex( *endOfBase = 0; result = TkTextWindowIndex(textPtr, Tcl_DStringValue(©), indexPtr); *endOfBase = c; - if (result != 0) { + if (result == TCL_OK) { goto gotBase; } } @@ -954,7 +954,7 @@ GetIndex( *endOfBase = 0; result = TkTextImageIndex(textPtr, Tcl_DStringValue(©), indexPtr); *endOfBase = c; - if (result != 0) { + if (result == TCL_OK) { goto gotBase; } } @@ -997,6 +997,7 @@ GetIndex( if (indexPtr->linePtr == NULL) { Tcl_Panic("Bad index created"); } + TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 0); return TCL_OK; error: @@ -1009,6 +1010,67 @@ GetIndex( /* *--------------------------------------------------------------------------- * + * TkTextIndexAdjustToStartEnd -- + * + * Adjust indexPtr to the -startline/-endline range, or just check + * if indexPtr is out of this range. + * + * Results: + * The return value is a standard Tcl return result. If check is true, + * return TCL_ERROR if indexPtr is outside the -startline/-endline + * range (indexPtr is not modified). + * If check is false, adjust indexPtr to -startline/-endline. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +int +TkTextIndexAdjustToStartEnd( + TkText *textPtr, + TkTextIndex *indexPtr, /* Pointer to index. */ + int check) /* 1 means only check indexPtr against + * the -startline/-endline range + * 0 means adjust to this range */ +{ + int bound; + TkTextIndex indexBound; + + if (!textPtr) { + return TCL_OK; + } + if (textPtr->start != NULL) { + bound = TkBTreeLinesTo(NULL, textPtr->start); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0, + &indexBound); + if (TkTextIndexCmp(indexPtr, &indexBound) < 0) { + if (check) { + return TCL_ERROR; + } + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0, + indexPtr); + } + } + if (textPtr->end != NULL) { + bound = TkBTreeLinesTo(NULL, textPtr->end); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0, + &indexBound); + if (TkTextIndexCmp(indexPtr, &indexBound) > 0) { + if (check) { + return TCL_ERROR; + } + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, bound, 0, + indexPtr); + } + } + return TCL_OK; +} + +/* + *--------------------------------------------------------------------------- + * * TkTextPrintIndex -- * * This function generates a string description of an index, suitable for diff --git a/generic/tkTextMark.c b/generic/tkTextMark.c index 5d4b5d5..9efa222 100644 --- a/generic/tkTextMark.c +++ b/generic/tkTextMark.c @@ -434,8 +434,6 @@ TkTextMarkNameToIndex( TkTextIndex *indexPtr) /* Index information gets stored here. */ { TkTextSegment *segPtr; - TkTextIndex index; - int start, end; if (textPtr == NULL) { return TCL_ERROR; @@ -456,28 +454,17 @@ TkTextMarkNameToIndex( } TkTextMarkSegToIndex(textPtr, segPtr, indexPtr); - /* If indexPtr refers to somewhere outside the -startline/-endline + /* + * If indexPtr refers to somewhere outside the -startline/-endline * range limits of the widget, error out since the mark indeed is not * reachable from this text widget (it may be reachable from a peer) * (bug 1630271). */ - if (textPtr->start != NULL) { - start = TkBTreeLinesTo(NULL, textPtr->start); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0, - &index); - if (TkTextIndexCmp(indexPtr, &index) < 0) { - return TCL_ERROR; - } - } - if (textPtr->end != NULL) { - end = TkBTreeLinesTo(NULL, textPtr->end); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, end, 0, - &index); - if (TkTextIndexCmp(indexPtr, &index) > 0) { - return TCL_ERROR; - } + if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) { + return TCL_ERROR; } + return TCL_OK; } diff --git a/generic/tkTextWind.c b/generic/tkTextWind.c index adf1ad5..a43293f 100644 --- a/generic/tkTextWind.c +++ b/generic/tkTextWind.c @@ -1320,9 +1320,9 @@ EmbWinDelayedUnmap( * index corresponding to the window's position in the text. * * Results: - * The return value is 1 if there is an embedded window by the given name - * in the text widget, 0 otherwise. If the window exists, *indexPtr is - * filled in with its index. + * The return value is TCL_OK if there is an embedded window by the given + * name in the text widget, TCL_ERROR otherwise. If the window exists, + * *indexPtr is filled in with its index. * * Side effects: * None. @@ -1340,19 +1340,30 @@ TkTextWindowIndex( TkTextSegment *ewPtr; if (textPtr == NULL) { - return 0; + return TCL_ERROR; } hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->windowTable, name); if (hPtr == NULL) { - return 0; + return TCL_ERROR; } ewPtr = (TkTextSegment *)Tcl_GetHashValue(hPtr); indexPtr->tree = textPtr->sharedTextPtr->tree; indexPtr->linePtr = ewPtr->body.ew.linePtr; indexPtr->byteIndex = TkTextSegToOffset(ewPtr, indexPtr->linePtr); - return 1; + + /* + * If indexPtr refers to somewhere outside the -startline/-endline + * range limits of the widget, error out since the window indeed is not + * reachable from this text widget (it may be reachable from a peer). + */ + + if (TkTextIndexAdjustToStartEnd(textPtr, indexPtr, 1) == TCL_ERROR) { + return TCL_ERROR; + } + + return TCL_OK; } /* diff --git a/tests/textIndex.test b/tests/textIndex.test index 2d42b8e..f2cccac 100644 --- a/tests/textIndex.test +++ b/tests/textIndex.test @@ -964,6 +964,43 @@ test textIndex-25.1 {IndexCountBytesOrdered, bug [3f1f79abcf]} { destroy .t2 } {} +test textIndex-26.1 {GetIndex restricts the returned index to -starline/-endline in peers, bug [34db75c0ac]} { + set res {} + pack [text .t2] + .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n" + pack [.t2 peer create .p2 -startline 2 -endline 3] + lappend res [.p2 index "end"] + lappend res [.p2 index "end lineend"] + lappend res [.p2 index "end display lineend"] + destroy .t2 .p2 + set res +} {2.0 2.0 2.0} +test textIndex-26.2 {GetIndex errors out if mark, image, window, or tag is outside peer -starline/-endline, bug [34db75c0ac]} { + set res {} + pack [text .t2] + .t2 insert end "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\n" + pack [.t2 peer create .p2 -startline 2 -endline 3] + .p2 configure -startline 3 -endline {} + .t2 mark set mymark 1.0 + catch {.p2 index mymark} msg + lappend res [.t2 index mymark] $msg + image create photo redsquare -width 5 -height 5 + redsquare put red -to 0 0 4 4 + .t2 image create 1.0 -image redsquare + catch {.p2 index redsquare} msg + lappend res [.t2 index redsquare] $msg + frame .f -width 10 -height 10 -bg blue + .t2 window create 1.2 -window .f + catch {.p2 index .f} msg + lappend res [.t2 index .f] $msg + .t2 tag add mytag 1.3 + catch {.p2 index mytag.first} msg + lappend res [.t2 index mytag.first] $msg + destroy .t2 .p2 + set res +} {1.0 {bad text index "mymark"} 1.0 {bad text index "redsquare"} 1.2\ + {bad text index ".f"} 1.3 {text doesn't contain any characters tagged with "mytag"}} + # cleanup rename textimage {} catch {destroy .t} diff --git a/tests/textMark.test b/tests/textMark.test index 938ce7f..bbe839f 100644 --- a/tests/textMark.test +++ b/tests/textMark.test @@ -182,6 +182,17 @@ test textMark-6.5 {insert and current marks in an empty peer - bug 3487407} -bod } -cleanup { .t configure -startline {} -endline {} } -result {1.0} +test textMark-6.6 {attempt to move the insert mark beyond peer -endline - bug 34db75c0ac} -body { + .t peer create .p -startline 1 -endline 2 + pack .p + update + .p mark set insert 1.2 + focus -force .p + event generate .p <<NextLine>> ; # shall not error out + set res [.p index insert] +} -cleanup { + destroy .p +} -result {1.9} test textMark-7.1 {MarkFindNext - invalid mark name} -body { .t mark next bogus |