diff options
-rw-r--r-- | misc.c | 39 |
1 files changed, 24 insertions, 15 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: misc.c,v 1.139 2019/06/28 13:35:04 deraadt Exp $ */ | 1 | /* $OpenBSD: misc.c,v 1.140 2019/08/16 06:13:15 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2005,2006 Damien Miller. All rights reserved. |
@@ -1049,13 +1049,18 @@ char * | |||
1049 | percent_expand(const char *string, ...) | 1049 | percent_expand(const char *string, ...) |
1050 | { | 1050 | { |
1051 | #define EXPAND_MAX_KEYS 16 | 1051 | #define EXPAND_MAX_KEYS 16 |
1052 | u_int num_keys, i, j; | 1052 | u_int num_keys, i; |
1053 | struct { | 1053 | struct { |
1054 | const char *key; | 1054 | const char *key; |
1055 | const char *repl; | 1055 | const char *repl; |
1056 | } keys[EXPAND_MAX_KEYS]; | 1056 | } keys[EXPAND_MAX_KEYS]; |
1057 | char buf[4096]; | 1057 | struct sshbuf *buf; |
1058 | va_list ap; | 1058 | va_list ap; |
1059 | int r; | ||
1060 | char *ret; | ||
1061 | |||
1062 | if ((buf = sshbuf_new()) == NULL) | ||
1063 | fatal("%s: sshbuf_new failed", __func__); | ||
1059 | 1064 | ||
1060 | /* Gather keys */ | 1065 | /* Gather keys */ |
1061 | va_start(ap, string); | 1066 | va_start(ap, string); |
@@ -1072,14 +1077,13 @@ percent_expand(const char *string, ...) | |||
1072 | va_end(ap); | 1077 | va_end(ap); |
1073 | 1078 | ||
1074 | /* Expand string */ | 1079 | /* Expand string */ |
1075 | *buf = '\0'; | ||
1076 | for (i = 0; *string != '\0'; string++) { | 1080 | for (i = 0; *string != '\0'; string++) { |
1077 | if (*string != '%') { | 1081 | if (*string != '%') { |
1078 | append: | 1082 | append: |
1079 | buf[i++] = *string; | 1083 | if ((r = sshbuf_put_u8(buf, *string)) != 0) { |
1080 | if (i >= sizeof(buf)) | 1084 | fatal("%s: sshbuf_put_u8: %s", |
1081 | fatal("%s: string too long", __func__); | 1085 | __func__, ssh_err(r)); |
1082 | buf[i] = '\0'; | 1086 | } |
1083 | continue; | 1087 | continue; |
1084 | } | 1088 | } |
1085 | string++; | 1089 | string++; |
@@ -1088,18 +1092,23 @@ percent_expand(const char *string, ...) | |||
1088 | goto append; | 1092 | goto append; |
1089 | if (*string == '\0') | 1093 | if (*string == '\0') |
1090 | fatal("%s: invalid format", __func__); | 1094 | fatal("%s: invalid format", __func__); |
1091 | for (j = 0; j < num_keys; j++) { | 1095 | for (i = 0; i < num_keys; i++) { |
1092 | if (strchr(keys[j].key, *string) != NULL) { | 1096 | if (strchr(keys[i].key, *string) != NULL) { |
1093 | i = strlcat(buf, keys[j].repl, sizeof(buf)); | 1097 | if ((r = sshbuf_put(buf, keys[i].repl, |
1094 | if (i >= sizeof(buf)) | 1098 | strlen(keys[i].repl))) != 0) { |
1095 | fatal("%s: string too long", __func__); | 1099 | fatal("%s: sshbuf_put: %s", |
1100 | __func__, ssh_err(r)); | ||
1101 | } | ||
1096 | break; | 1102 | break; |
1097 | } | 1103 | } |
1098 | } | 1104 | } |
1099 | if (j >= num_keys) | 1105 | if (i >= num_keys) |
1100 | fatal("%s: unknown key %%%c", __func__, *string); | 1106 | fatal("%s: unknown key %%%c", __func__, *string); |
1101 | } | 1107 | } |
1102 | return (xstrdup(buf)); | 1108 | if ((ret = sshbuf_dup_string(buf)) == NULL) |
1109 | fatal("%s: sshbuf_dup_string failed", __func__); | ||
1110 | sshbuf_free(buf); | ||
1111 | return ret; | ||
1103 | #undef EXPAND_MAX_KEYS | 1112 | #undef EXPAND_MAX_KEYS |
1104 | } | 1113 | } |
1105 | 1114 | ||