summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-10-02 19:55:30 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-10-02 19:55:30 +0000
commit377f2bb8124d441e6927856c51e61c40516ae09e (patch)
tree31109b2d8cd174c74e093d8cb5f23dd240a7b67f
parentdcaaf028569c5e08487de297aee8f02328f0f30f (diff)
downloadzsh-377f2bb8124d441e6927856c51e61c40516ae09e.tar.gz
zsh-377f2bb8124d441e6927856c51e61c40516ae09e.zip
28309: fix infinite loop padding with extra wide characters
-rw-r--r--ChangeLog5
-rw-r--r--Src/subst.c60
2 files changed, 58 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index 246d2c13c..5f8016c71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
2010-10-02 Peter Stephenson <p.w.stephenson@ntlworld.com>
+ * 28309: Src/subst.c: infinite loop when padding with extra wide
+ characters.
+
* Mikael: 28301: Doc/Zsh/compsys.yo: restore missing line.
2010-10-01 Oliver Kiddle <opk@zsh.org>
@@ -13686,5 +13689,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5089 $
+* $Revision: 1.5090 $
*****************************************************
diff --git a/Src/subst.c b/Src/subst.c
index 2543c7cce..cace51e8c 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -802,12 +802,17 @@ dopadding(char *str, int prenum, int postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
/* 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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
/* 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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
/* 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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
*/
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 postnum, char *preone, char *postone,
*/
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 postnum, char *preone, char *postone,
*/
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 postnum, char *preone, char *postone,
/* 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 postnum, char *preone, char *postone,
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 postnum, char *preone, char *postone,
MB_METACHARINIT();
while (m > 0) {
cl = MB_METACHARLENCONV(postmul, &cchar);
+ if (!cl)
+ break;
while (cl--)
*r++ = *postmul++;
m -= WCPADWIDTH(cchar, multi_width);