| 1113 | } |
| 1114 | |
| 1115 | static size_t parse_padding_placeholder(const char *placeholder, |
| 1116 | struct format_commit_context *c) |
| 1117 | { |
| 1118 | const char *ch = placeholder; |
| 1119 | enum flush_type flush_type; |
| 1120 | int to_column = 0; |
| 1121 | |
| 1122 | switch (*ch++) { |
| 1123 | case '<': |
| 1124 | flush_type = flush_right; |
| 1125 | break; |
| 1126 | case '>': |
| 1127 | if (*ch == '<') { |
| 1128 | flush_type = flush_both; |
| 1129 | ch++; |
| 1130 | } else if (*ch == '>') { |
| 1131 | flush_type = flush_left_and_steal; |
| 1132 | ch++; |
| 1133 | } else |
| 1134 | flush_type = flush_left; |
| 1135 | break; |
| 1136 | default: |
| 1137 | return 0; |
| 1138 | } |
| 1139 | |
| 1140 | /* the next value means "wide enough to that column" */ |
| 1141 | if (*ch == '|') { |
| 1142 | to_column = 1; |
| 1143 | ch++; |
| 1144 | } |
| 1145 | |
| 1146 | if (*ch == '(') { |
| 1147 | const char *start = ch + 1; |
| 1148 | const char *end = start + strcspn(start, ",)"); |
| 1149 | char *next; |
| 1150 | int width; |
| 1151 | if (!*end || end == start) |
| 1152 | return 0; |
| 1153 | width = strtol(start, &next, 10); |
| 1154 | |
| 1155 | /* |
| 1156 | * We need to limit the amount of padding, or otherwise this |
| 1157 | * would allow the user to pad the buffer by arbitrarily many |
| 1158 | * bytes and thus cause resource exhaustion. |
| 1159 | */ |
| 1160 | if (width < -FORMATTING_LIMIT || width > FORMATTING_LIMIT) |
| 1161 | return 0; |
| 1162 | |
| 1163 | if (next == start || width == 0) |
| 1164 | return 0; |
| 1165 | if (width < 0) { |
| 1166 | if (to_column) |
| 1167 | width += term_columns(); |
| 1168 | if (width < 0) |
| 1169 | return 0; |
| 1170 | } |
| 1171 | c->padding = to_column ? -width : width; |
| 1172 | c->flush_type = flush_type; |
no test coverage detected