tlibdraw, libframe, acme: fix, guard against inverted range in textsetselect - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit fff818fe878ca5edfbac85b15e77ada2acb8ea0f
 (DIR) parent d3a47e14e5ebf7a4d8ca8c9a3dfe748b93d3663a
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Mon,  1 Dec 2014 20:15:52 -0500
       
       libdraw, libframe, acme: fix, guard against inverted range in textsetselect
       
       Credit to Roi Martin <jroi.martin@gmail.com> for noticing that
       libdraw was being passed a negative string length and for finding the
       sequence of keystrokes that make acme do it reproducibly.
       
       Change-Id: If3f3d04a25c506175f740d3e887d5d83b5cd1bfe
       Reviewed-on: https://plan9port-review.googlesource.com/1092
       Reviewed-by: Russ Cox <rsc@swtch.com>
       
       Diffstat:
         M src/cmd/acme/text.c                 |      12 +++++++++---
         M src/libdraw/string.c                |       3 +++
         M src/libframe/frdraw.c               |       3 +++
       
       3 files changed, 15 insertions(+), 3 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
       t@@ -819,8 +819,12 @@ texttype(Text *t, Rune r)
                        nr = runestrlen(rp);
                        break;        /* fall through to normal insertion case */
                case 0x1B:
       -                if(t->eq0 != ~0)
       -                        textsetselect(t, t->eq0, t->q0);
       +                if(t->eq0 != ~0) {
       +                        if(t->eq0 <= t->q0)
       +                                textsetselect(t, t->eq0, t->q0);
       +                        else
       +                                textsetselect(t, t->q0, t->eq0);
       +                }
                        if(t->ncache > 0)
                                typecommit(t);
                        t->iq1 = t->q0;
       t@@ -1173,7 +1177,7 @@ void
        textsetselect(Text *t, uint q0, uint q1)
        {
                int p0, p1, ticked;
       -
       +        
                /* t->fr.p0 and t->fr.p1 are always right; t->q0 and t->q1 may be off */
                t->q0 = q0;
                t->q1 = q1;
       t@@ -1198,6 +1202,8 @@ textsetselect(Text *t, uint q0, uint q1)
                                frtick(&t->fr, frptofchar(&t->fr, p0), ticked);
                        return;
                }
       +        if(p0 > p1)
       +                sysfatal("acme: textsetselect p0=%d p1=%d q0=%ud q1=%ud t->org=%d nchars=%d", p0, p1, q0, q1, (int)t->org, (int)t->fr.nchars);
                /* screen disagrees with desired selection */
                if(t->fr.p1<=p0 || p1<=t->fr.p0 || p0==p1 || t->fr.p1==t->fr.p0){
                        /* no overlap or too easy to bother trying */
 (DIR) diff --git a/src/libdraw/string.c b/src/libdraw/string.c
       t@@ -67,6 +67,9 @@ _string(Image *dst, Point pt, Image *src, Point sp, Font *f, char *s, Rune *r, i
                Font *def;
                Subfont *sf;
        
       +        if(len < 0)
       +                sysfatal("libdraw: _string len=%d", len);
       +
                if(s == nil){
                        s = "";
                        sptr = nil;
 (DIR) diff --git a/src/libframe/frdraw.c b/src/libframe/frdraw.c
       t@@ -62,6 +62,9 @@ frdrawsel0(Frame *f, Point pt, ulong p0, ulong p1, Image *back, Image *text)
                Point qt;
                uint p;
                char *ptr;
       +        
       +        if(p0 > p1)
       +                sysfatal("libframe: frdrawsel0 p0=%lud > p1=%lud", p0, p1);
        
                p = 0;
                b = f->box;