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);