Package: libstfl-dev
Version: 0.21-2+b1
Severity: normal
Tags: patch

If multi-column characters are entered to an input widget and
they are exposed, the text overflows.
The attached screenshot was taken while running attached input.c.

-- System Information:
Debian Release: squeeze/sid
  APT prefers unstable
  APT policy: (1001, 'unstable'), (500, 'unstable'), (1, 'experimental')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.37-rc1 (SMP w/4 CPU cores)
Locale: LANG=ja_JP.eucJP, LC_CTYPE=ja_JP.eucJP (charmap=EUC-JP)
Shell: /bin/sh linked to /bin/dash

Versions of packages libstfl-dev depends on:
ii  libncursesw5-dev          5.7+20100313-4 developer's libraries for ncursesw

libstfl-dev recommends no packages.

libstfl-dev suggests no packages.

-- no debconf information
#include <stfl.h>
#include <locale.h>

int main(void)
{
    struct stfl_form *form;
    const wchar_t *wcs;

    if (setlocale(LC_ALL, "") == NULL)
    {
	return 1;
    }

    form = stfl_create(L"table\n label .expand:0\n !input[i] .border:lrtb .expand:h pos[pos]: offset[off]:\n tablebr\n label .expand:0 text:width\n label .expand:h text[w]:\n tablebr\n label .expand:0 text:pos\n label .expand:h text[p]:\n tablebr\n label .expand:0 text:offset\n label .expand:h text[o]:");

    stfl_run(form, -3);
    stfl_set(form, L"w", stfl_get(form, L"i:w"));
    wcs = stfl_get(form, L"pos");
    stfl_set(form, L"p", wcscmp(wcs, L"")? wcs: L"0");
    wcs = stfl_get(form, L"off");
    stfl_set(form, L"o", wcscmp(wcs, L"")? wcs: L"0");

    while (stfl_run(form, 0) == NULL)
    {
	stfl_set(form, L"label", stfl_get_focus(form));
	wcs = stfl_get(form, L"pos");
	stfl_set(form, L"p", wcscmp(wcs, L"")? wcs: L"0");
	wcs = stfl_get(form, L"off");
	stfl_set(form, L"o", wcscmp(wcs, L"")? wcs: L"0");
    }

    stfl_reset();
    stfl_free(form);
    return 0;
}

<<attachment: screenshot.png>>

--- stfl-0.21.orig/widgets/wt_input.c   2007-10-13 07:45:09.000000000 +0000
+++ stfl-0.21/widgets/wt_input.c        2010-11-12 10:21:29.645201794 +0000
@@ -38,32 +38,21 @@
        const wchar_t* text = stfl_widget_getkv_str(w, L"text", L"");
        int text_len = wcslen(text);
        int changed = 0;
-       int pos_width = 0;
-       int offset_width = 0;
-       int i;
+       int width;
 
        if (pos > text_len) {
                pos = text_len;
                changed = 1;
        }
 
-       if (offset > text_len) {
-               offset = text_len;
-               changed = 1;
-       }
-
        if (offset > pos) {
                offset = pos;
                changed = 1;
        }
 
-       for (i=0;i<pos;++i) {
-               pos_width += wcwidth(text[i]);
-       }
-
-       while (text[offset] && pos-offset >= w->w && pos_width-offset_width >= 
w->w && w->w > 0) {
-               offset_width += wcwidth(text[offset]);
-               offset++;
+       width = wcswidth(text + offset, pos - offset);
+       while (width >= w->w && pos > offset) {
+               width -= wcwidth(text[offset++]);
                changed = 1;
        }
 
@@ -88,26 +77,30 @@
        int pos = stfl_widget_getkv_int(w, L"pos", 0);
        int blind = stfl_widget_getkv_int(w, L"blind", 0);
        int offset = stfl_widget_getkv_int(w, L"offset", 0);
-       const wchar_t *text = stfl_widget_getkv_str(w, L"text", L"");
-       int pos_width = 0, offset_width = 0, i;
+       const wchar_t * const text_off = stfl_widget_getkv_str(w, L"text", L"") 
+ offset;
+       int i;
 
        stfl_widget_style(w, f, win);
 
        for (i=0; i<w->w; i++)
                mvwaddwstr(win, w->y, w->x+i, L" ");
-       if (!blind)
-               mvwaddnwstr(win, w->y, w->x, text+offset, 
wcswidth(text+offset,w->w));
-
-       for (i=0;i<pos;++i) {
-               pos_width += wcwidth(text[i]);
-       }
 
-       for (i=0;i<offset;++i) {
-               offset_width += wcwidth(text[i]);
+       if (!blind) {
+               const int off_len = wcslen(text_off);
+               int width, len;
+
+               width = wcswidth(text_off, w->w);
+               if (w->w > off_len)
+                       len = off_len;
+               else
+                       len = w->w;
+               while (width > w->w)
+                       width -= wcwidth(text_off[--len]);
+               mvwaddnwstr(win, w->y, w->x, text_off, len);
        }
 
        if (f->current_focus_id == w->id) {
-               f->cursor_x = w->x + pos_width - offset_width;
+               f->cursor_x = w->x + wcswidth(text_off, pos - offset);
                f->cursor_y = w->y;
        }
 }
@@ -150,8 +143,7 @@
                        return 0;
                wchar_t newtext[text_len];
                wmemcpy(newtext, text, pos);
-               wmemcpy(newtext+pos, text+pos+1, text_len-(pos+1));
-               newtext[text_len-1] = 0;
+               wcscpy(newtext + pos, text + pos + 1);
                stfl_widget_setkv_str(w, L"text", newtext);
                fix_offset_pos(w);
                return 1;
@@ -163,8 +155,7 @@
                        return 0;
                wchar_t newtext[text_len];
                wmemcpy(newtext, text, pos-1);
-               wmemcpy(newtext+pos-1, text+pos, text_len-pos);
-               newtext[text_len-1] = 0;
+               wcscpy(newtext + pos - 1, text + pos);
                stfl_widget_setkv_str(w, L"text", newtext);
                stfl_widget_setkv_int(w, L"pos", pos-1);
                fix_offset_pos(w);
@@ -176,8 +167,7 @@
                wchar_t newtext[text_len + 2];
                wmemcpy(newtext, text, pos);
                newtext[pos] = ch;
-               wmemcpy(newtext+pos+1, text+pos, text_len - pos);
-               newtext[text_len + 1] = 0;
+               wcscpy(newtext + pos + 1, text + pos);
                stfl_widget_setkv_str(w, L"text", newtext);
                stfl_widget_setkv_int(w, L"pos", pos+1);
                fix_offset_pos(w);

Reply via email to