Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Infinite loop in dopadding() with doublewidth chars, probably since (mm)
- X-seq: zsh-workers 28306
- From: Mikael Magnusson <mikachu@xxxxxxxxx>
- To: zsh workers <zsh-workers@xxxxxxx>
- Subject: Infinite loop in dopadding() with doublewidth chars, probably since (mm)
- Date: Wed, 29 Sep 2010 00:51:58 +0200
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:date:message-id :subject:from:to:content-type:content-transfer-encoding; bh=dNiLw91itZ3yoLQRG7m6rEp5CEIaKM1oparL3RdfwYQ=; b=LfdwApM+jJtCb5dkZvagnRup3+MT7PMA7C8oa39KAH9YAXEIAEd7mvVO4w4mHEDvlq Q2ZRB+gpbgp6+pCzzsnxzM1K3u8b3UgRQFJEj8umZw749m2rWvh2dSsRqFmNSJ7Pww/q +7LQNxUjw5lkp7lDzd2Q7JZkwTxQtHc5fdUD4=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type :content-transfer-encoding; b=f/MUwUn42E+N6tNO6QnEsu+NYlNvksLVzI/xWDznhxSNOBQznd+uF+4HBbe4DVZ1Vd ibKbxb408oPtPRHWFi+ZiqTSYYUBh96VP3xF5i/MxnXijOgzj2bT6FuUYbllV1QvyxTl hXXgJxQVgbBOgBLAS7VdIbfKQe08RUDwmo/do=
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Trying to pad a string to a width with a double-width character that
can't be done results in an infinite loop, where old versions just
left it one character too narrow. For example:
echo ${(ml:10::ã:):-hello}
dopadding() seems to consist mostly of special cases, but i ended up
around line 990,
986 if ((m = f % lpremul)) {
here f is 5 "hello", lpremul is 2 "ã", so m is 1
987 /*
988 * Some fraction of the repeated string needed.
989 */
990 /* Need this much... */
991 c = m;
992 /* ...skipping this much first. */
993 m = lpremul - m;
m is still 1 here
994 MB_METACHARINIT();
995 for (t = premul; m > 0; ) {
996 t += MB_METACHARLENCONV(t, &cchar);
this advances t 3 bytes, pointing directly at the null after the ã
997 m -= WCPADWIDTH(cchar, multi_width);
this subtracts 2 from m, leaving -1
998 }
999 /* Now the rest of the repeated string. */
1000 while (c > 0) {
c is still 1 here
1001 cl = MB_METACHARLENCONV(t, &cchar);
this is 0, remember t is ""
1002 while (cl--)
1003 *r++ = *t++;
1004 c -= WCPADWIDTH(cchar, multi_width);
which means c is decremented by 0 here
1005 }
1006 }
I didn't get much further than this. I didn't even dare look in how
many places some similar code exists in the function. :)
--
Mikael Magnusson
Messages sorted by:
Reverse Date,
Date,
Thread,
Author