+ {
+ if (incr == INTMAX_MIN) /* Don't use -INTMAX_MIN */
+ return ((char **)NULL);
+ incr = -incr;
+ }
+
+ /* Check that end-start will not overflow INTMAX_MIN, INTMAX_MAX. The +3
+ and -2, not strictly necessary, are there because of the way the number
+ of elements and value passed to strvec_create() are calculated below. */
+ if (SUBOVERFLOW (end, start, INTMAX_MIN+3, INTMAX_MAX-2))
+ return ((char **)NULL);
+
+ prevn = sh_imaxabs (end - start);
+ /* Need to check this way in case INT_MAX == INTMAX_MAX */
+ if (INT_MAX == INTMAX_MAX && (ADDOVERFLOW (prevn, 2, INT_MIN, INT_MAX)))
+ return ((char **)NULL);
+ /* Make sure the assignment to nelem below doesn't end up <= 0 due to
+ intmax_t overflow */
+ else if (ADDOVERFLOW ((prevn/sh_imaxabs(incr)), 1, INTMAX_MIN, INTMAX_MAX))
+ return ((char **)NULL);
+
+ /* XXX - TOFIX: potentially allocating a lot of extra memory if
+ imaxabs(incr) != 1 */
+ /* Instead of a simple nelem = prevn + 1, something like:
+ nelem = (prevn / imaxabs(incr)) + 1;
+ would work */
+ nelem = (prevn / sh_imaxabs(incr)) + 1;
+ if (nelem > INT_MAX - 2) /* Don't overflow int */
+ return ((char **)NULL);
+ result = strvec_mcreate (nelem + 1);
+ if (result == 0)
+ {
+ internal_error (_("brace expansion: failed to allocate memory for %d elements"), nelem);
+ return ((char **)NULL);
+ }