From: Peter Stephenson <p.w.stephenson@ntlworld.com>
To: zsh workers <zsh-workers@zsh.org>
Subject: Re: Infinite loop in dopadding() with doublewidth chars, probably since (mm)
Date: Sat, 2 Oct 2010 19:41:11 +0100 [thread overview]
Message-ID: <20101002194111.2a76ca95@pws-pc> (raw)
In-Reply-To: <AANLkTikohC-rVB5Cif2HrdoQjbkSwkksEOeRATdDW4LZ@mail.gmail.com>
On Wed, 29 Sep 2010 00:51:58 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> 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}
I suppose we just have to stop when there's nothing left.
Index: Src/subst.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/subst.c,v
retrieving revision 1.106
diff -p -u -r1.106 subst.c
--- Src/subst.c 11 Jun 2010 20:08:03 -0000 1.106
+++ Src/subst.c 2 Oct 2010 18:38:42 -0000
@@ -802,12 +802,17 @@ dopadding(char *str, int prenum, int pos
f = -f;
MB_METACHARINIT();
while (f > 0) {
- str += MB_METACHARLENCONV(str, &cchar);
+ cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
+ str += cl;
f -= WCPADWIDTH(cchar, multi_width);
}
/* Now finish the first half. */
for (c = prenum; c > 0; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *str++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -823,7 +828,10 @@ dopadding(char *str, int prenum, int pos
f = lpreone - f;
/* So skip. */
for (t = preone; f > 0; ) {
- t += MB_METACHARLENCONV(t, &cchar);
+ cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
+ t += cl;
f -= WCPADWIDTH(cchar, multi_width);
}
/* Then copy the entire remainder. */
@@ -841,7 +849,10 @@ dopadding(char *str, int prenum, int pos
/* Skip this much. */
m = lpremul - m;
for (t = premul; m > 0; ) {
- t += MB_METACHARLENCONV(t, &cchar);
+ cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
+ t += cl;
m -= WCPADWIDTH(cchar, multi_width);
}
/* Output the rest. */
@@ -853,6 +864,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
for (c = lpremul, t = premul; c > 0; ) {
cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *t++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -868,6 +881,8 @@ dopadding(char *str, int prenum, int pos
/* Output the first half width of the original string. */
for (c = ls2; c > 0; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
c -= WCPADWIDTH(cchar, multi_width);
while (cl--)
*r++ = *str++;
@@ -882,6 +897,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
for (c = postnum; c > 0; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
c -= WCPADWIDTH(cchar, multi_width);
while (cl--)
*r++ = *str++;
@@ -895,6 +912,8 @@ dopadding(char *str, int prenum, int pos
/* Can't fit unrepeated string, truncate it */
for (c = f; c > 0; ) {
cl = MB_METACHARLENCONV(postone, &cchar);
+ if (!cl)
+ break;
c -= WCPADWIDTH(cchar, multi_width);
while (cl--)
*r++ = *postone++;
@@ -918,6 +937,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
while (m > 0) {
cl = MB_METACHARLENCONV(postmul, &cchar);
+ if (!cl)
+ break;
m -= WCPADWIDTH(cchar, multi_width);
while (cl--)
*r++ = *postmul++;
@@ -941,12 +962,17 @@ dopadding(char *str, int prenum, int pos
f = -f;
MB_METACHARINIT();
while (f > 0) {
- str += MB_METACHARLENCONV(str, &cchar);
+ cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
+ str += cl;
f -= WCPADWIDTH(cchar, multi_width);
}
/* Copy the rest of the original string */
for (c = prenum; c > 0; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *str++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -969,7 +995,10 @@ dopadding(char *str, int prenum, int pos
f = lpreone - f;
MB_METACHARINIT();
for (t = preone; f > 0; ) {
- t += MB_METACHARLENCONV(t, &cchar);
+ cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
+ t += cl;
f -= WCPADWIDTH(cchar, multi_width);
}
/* Copy the rest of preone */
@@ -993,12 +1022,17 @@ dopadding(char *str, int prenum, int pos
m = lpremul - m;
MB_METACHARINIT();
for (t = premul; m > 0; ) {
- t += MB_METACHARLENCONV(t, &cchar);
+ cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
+ t += cl;
m -= WCPADWIDTH(cchar, multi_width);
}
/* Now the rest of the repeated string. */
while (c > 0) {
cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *t++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1011,6 +1045,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
for (c = lpremul, t = premul; c > 0; ) {
cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *t++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1049,6 +1085,8 @@ dopadding(char *str, int prenum, int pos
*/
for (c = postnum; c > 0; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *str++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1061,6 +1099,8 @@ dopadding(char *str, int prenum, int pos
*/
for (c = ls; *str; ) {
cl = MB_METACHARLENCONV(str, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *str++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1074,6 +1114,8 @@ dopadding(char *str, int prenum, int pos
*/
for (c = f; c > 0; ) {
cl = MB_METACHARLENCONV(postone, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *postone++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1085,6 +1127,8 @@ dopadding(char *str, int prenum, int pos
/* Copy the entire unrepeated string */
for (c = lpostone; *postone; ) {
cl = MB_METACHARLENCONV(postone, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *postone++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1096,6 +1140,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
for (c = lpostmul, t = postmul; *t; ) {
cl = MB_METACHARLENCONV(t, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *t++;
c -= WCPADWIDTH(cchar, multi_width);
@@ -1109,6 +1155,8 @@ dopadding(char *str, int prenum, int pos
MB_METACHARINIT();
while (m > 0) {
cl = MB_METACHARLENCONV(postmul, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *postmul++;
m -= WCPADWIDTH(cchar, multi_width);
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
prev parent reply other threads:[~2010-10-02 19:43 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-28 22:51 Mikael Magnusson
2010-10-02 18:41 ` Peter Stephenson [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20101002194111.2a76ca95@pws-pc \
--to=p.w.stephenson@ntlworld.com \
--cc=zsh-workers@zsh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).