Simplify tdeletechar and tinsertblank and fix memory corruption. - st - Personal fork of st
 (HTM) git clone git://git.drkhsh.at/st.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 80b32af794b659cb15745cfb2a19fce0829c42c7
 (DIR) parent 16ac85bf5422a7e925743f6134572d3ac1a25188
 (HTM) Author: noname <noname@inventati.org>
       Date:   Wed, 23 Apr 2014 02:08:13 +0400
       
       Simplify tdeletechar and tinsertblank and fix memory corruption.
       
       Current CSI parsing code uses strtol to parse arguments and allows them
       to be negative. Negative argument is not properly handled in tdeletechar
       and tinsertblank and results in memory corruption in memmove.
       
       Reproduce with printf '\e[-500@'
       
       Patch also removes special handling for corner case and simplifies
       the code.
       
       Removed
               term.dirty[term.c.y] = 1
       because tclearregion sets dirty flag.
       
       Diffstat:
         M st.c                                |      30 ++++++++++++------------------
       
       1 file changed, 12 insertions(+), 18 deletions(-)
       ---
 (DIR) diff --git a/st.c b/st.c
       @@ -1586,37 +1586,31 @@ tclearregion(int x1, int y1, int x2, int y2) {
        
        void
        tdeletechar(int n) {
       -        int src = term.c.x + n;
       -        int dst = term.c.x;
       -        int size = term.col - src;
       +        int dst, src, size;
        
       -        term.dirty[term.c.y] = 1;
       +        LIMIT(n, 0, term.col - term.c.x);
        
       -        if(src >= term.col) {
       -                tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
       -                return;
       -        }
       +        dst = term.c.x;
       +        src = term.c.x + n;
       +        size = term.col - src;
        
                memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
       -                        size * sizeof(Glyph));
       +                size * sizeof(Glyph));
                tclearregion(term.col-n, term.c.y, term.col-1, term.c.y);
        }
        
        void
        tinsertblank(int n) {
       -        int src = term.c.x;
       -        int dst = src + n;
       -        int size = term.col - dst;
       +        int dst, src, size;
        
       -        term.dirty[term.c.y] = 1;
       +        LIMIT(n, 0, term.col - term.c.x);
        
       -        if(dst >= term.col) {
       -                tclearregion(term.c.x, term.c.y, term.col-1, term.c.y);
       -                return;
       -        }
       +        dst = term.c.x + n;
       +        src = term.c.x;
       +        size = term.col - dst;
        
                memmove(&term.line[term.c.y][dst], &term.line[term.c.y][src],
       -                        size * sizeof(Glyph));
       +                size * sizeof(Glyph));
                tclearregion(src, term.c.y, dst - 1, term.c.y);
        }