diff options
-rw-r--r-- | miscutils/bc.c | 109 |
1 files changed, 76 insertions, 33 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 9eafa80e9..3da03b437 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -725,14 +725,39 @@ typedef unsigned long (*BcProgramBuiltIn)(BcNum *); | |||
725 | #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) | 725 | #define BC_MAX(a, b) ((a) > (b) ? (a) : (b)) |
726 | #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) | 726 | #define BC_MIN(a, b) ((a) < (b) ? (a) : (b)) |
727 | 727 | ||
728 | #define BC_MAX_OBASE ((unsigned) 999) | 728 | #define BC_MAX_OBASE ((unsigned) 999) |
729 | #define BC_MAX_DIM ((unsigned) INT_MAX) | 729 | #define BC_MAX_DIM ((unsigned) INT_MAX) |
730 | #define BC_MAX_SCALE ((unsigned) UINT_MAX) | 730 | #define BC_MAX_SCALE ((unsigned) UINT_MAX) |
731 | #define BC_MAX_STRING ((unsigned) UINT_MAX - 1) | 731 | #define BC_MAX_STRING ((unsigned) UINT_MAX - 1) |
732 | #define BC_MAX_NAME BC_MAX_STRING | 732 | #define BC_MAX_NUM BC_MAX_STRING |
733 | #define BC_MAX_NUM BC_MAX_STRING | 733 | // Unused apart from "limits" message. Just show a "biggish number" there. |
734 | #define BC_MAX_EXP ((unsigned long) LONG_MAX) | 734 | //#define BC_MAX_NAME BC_MAX_STRING |
735 | #define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1) | 735 | //#define BC_MAX_EXP ((unsigned long) LONG_MAX) |
736 | //#define BC_MAX_VARS ((unsigned long) SIZE_MAX - 1) | ||
737 | #define BC_MAX_NAME_STR "999999999" | ||
738 | #define BC_MAX_EXP_STR "999999999" | ||
739 | #define BC_MAX_VARS_STR "999999999" | ||
740 | |||
741 | #define BC_MAX_OBASE_STR "999" | ||
742 | |||
743 | #if INT_MAX == 2147483647 | ||
744 | # define BC_MAX_DIM_STR "2147483647" | ||
745 | #elif INT_MAX == 9223372036854775807 | ||
746 | # define BC_MAX_DIM_STR "9223372036854775807" | ||
747 | #else | ||
748 | # error Strange INT_MAX | ||
749 | #endif | ||
750 | |||
751 | #if UINT_MAX == 4294967295 | ||
752 | # define BC_MAX_SCALE_STR "4294967295" | ||
753 | # define BC_MAX_STRING_STR "4294967294" | ||
754 | #elif UINT_MAX == 18446744073709551615 | ||
755 | # define BC_MAX_SCALE_STR "18446744073709551615" | ||
756 | # define BC_MAX_STRING_STR "18446744073709551614" | ||
757 | #else | ||
758 | # error Strange UINT_MAX | ||
759 | #endif | ||
760 | #define BC_MAX_NUM_STR BC_MAX_STRING_STR | ||
736 | 761 | ||
737 | struct globals { | 762 | struct globals { |
738 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) | 763 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) |
@@ -1590,8 +1615,12 @@ static void bc_num_split(BcNum *restrict n, size_t idx, BcNum *restrict a, | |||
1590 | static BcStatus bc_num_shift(BcNum *n, size_t places) | 1615 | static BcStatus bc_num_shift(BcNum *n, size_t places) |
1591 | { | 1616 | { |
1592 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; | 1617 | if (places == 0 || n->len == 0) return BC_STATUS_SUCCESS; |
1593 | if (places + n->len > BC_MAX_NUM) | 1618 | |
1594 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | 1619 | // This check makes sense only if size_t is (much) larger than BC_MAX_NUM. |
1620 | if (SIZE_MAX > (BC_MAX_NUM | 0xff)) { | ||
1621 | if (places + n->len > BC_MAX_NUM) | ||
1622 | return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]"); | ||
1623 | } | ||
1595 | 1624 | ||
1596 | if (n->rdx >= places) | 1625 | if (n->rdx >= places) |
1597 | n->rdx -= places; | 1626 | n->rdx -= places; |
@@ -2891,8 +2920,11 @@ static BcStatus bc_lex_number(BcLex *l, char start) | |||
2891 | } | 2920 | } |
2892 | 2921 | ||
2893 | len = i + !last_pt - bslashes * 2; | 2922 | len = i + !last_pt - bslashes * 2; |
2894 | if (len > BC_MAX_NUM) | 2923 | // This check makes sense only if size_t is (much) larger than BC_MAX_NUM. |
2895 | return bc_error("number too long: must be [1, BC_NUM_MAX]"); | 2924 | if (SIZE_MAX > (BC_MAX_NUM | 0xff)) { |
2925 | if (len > BC_MAX_NUM) | ||
2926 | return bc_error("number too long: must be [1,"BC_MAX_NUM_STR"]"); | ||
2927 | } | ||
2896 | 2928 | ||
2897 | bc_vec_pop_all(&l->t.v); | 2929 | bc_vec_pop_all(&l->t.v); |
2898 | bc_vec_expand(&l->t.v, len + 1); | 2930 | bc_vec_expand(&l->t.v, len + 1); |
@@ -2929,8 +2961,11 @@ static BcStatus bc_lex_name(BcLex *l) | |||
2929 | 2961 | ||
2930 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; | 2962 | while ((c >= 'a' && c <= 'z') || isdigit(c) || c == '_') c = buf[++i]; |
2931 | 2963 | ||
2932 | if (i > BC_MAX_STRING) | 2964 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
2933 | return bc_error("name too long: must be [1, BC_NAME_MAX]"); | 2965 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
2966 | if (i > BC_MAX_STRING) | ||
2967 | return bc_error("name too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
2968 | } | ||
2934 | bc_vec_string(&l->t.v, i, buf); | 2969 | bc_vec_string(&l->t.v, i, buf); |
2935 | 2970 | ||
2936 | // Increment the index. We minus 1 because it has already been incremented. | 2971 | // Increment the index. We minus 1 because it has already been incremented. |
@@ -3047,8 +3082,11 @@ static BcStatus bc_lex_string(BcLex *l) | |||
3047 | } | 3082 | } |
3048 | 3083 | ||
3049 | len = i - l->i; | 3084 | len = i - l->i; |
3050 | if (len > BC_MAX_STRING) | 3085 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
3051 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | 3086 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
3087 | if (len > BC_MAX_STRING) | ||
3088 | return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
3089 | } | ||
3052 | bc_vec_string(&l->t.v, len, l->buf + l->i); | 3090 | bc_vec_string(&l->t.v, len, l->buf + l->i); |
3053 | 3091 | ||
3054 | l->i = i + 1; | 3092 | l->i = i + 1; |
@@ -3426,8 +3464,11 @@ static BcStatus dc_lex_string(BcLex *l) | |||
3426 | } | 3464 | } |
3427 | 3465 | ||
3428 | bc_vec_pushZeroByte(&l->t.v); | 3466 | bc_vec_pushZeroByte(&l->t.v); |
3429 | if (i - l->i > BC_MAX_STRING) | 3467 | // This check makes sense only if size_t is (much) larger than BC_MAX_STRING. |
3430 | return bc_error("string too long: must be [1, BC_STRING_MAX]"); | 3468 | if (SIZE_MAX > (BC_MAX_STRING | 0xff)) { |
3469 | if (i - l->i > BC_MAX_STRING) | ||
3470 | return bc_error("string too long: must be [1,"BC_MAX_STRING_STR"]"); | ||
3471 | } | ||
3431 | 3472 | ||
3432 | l->i = i; | 3473 | l->i = i; |
3433 | l->line += nls; | 3474 | l->line += nls; |
@@ -4700,14 +4741,16 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4700 | // the output is produced at _parse time_. | 4741 | // the output is produced at _parse time_. |
4701 | s = bc_lex_next(&p->l); | 4742 | s = bc_lex_next(&p->l); |
4702 | if (s) return s; | 4743 | if (s) return s; |
4703 | printf("BC_BASE_MAX = %u\n", BC_MAX_OBASE); | 4744 | printf( |
4704 | printf("BC_DIM_MAX = %u\n", BC_MAX_DIM); | 4745 | "BC_BASE_MAX = "BC_MAX_OBASE_STR "\n" |
4705 | printf("BC_SCALE_MAX = %u\n", BC_MAX_SCALE); | 4746 | "BC_DIM_MAX = "BC_MAX_DIM_STR "\n" |
4706 | printf("BC_STRING_MAX = %u\n", BC_MAX_STRING); | 4747 | "BC_SCALE_MAX = "BC_MAX_SCALE_STR "\n" |
4707 | printf("BC_NAME_MAX = %u\n", BC_MAX_NAME); | 4748 | "BC_STRING_MAX = "BC_MAX_STRING_STR"\n" |
4708 | printf("BC_NUM_MAX = %u\n", BC_MAX_NUM); | 4749 | "BC_NAME_MAX = "BC_MAX_NAME_STR "\n" |
4709 | printf("MAX Exponent = %lu\n", BC_MAX_EXP); | 4750 | "BC_NUM_MAX = "BC_MAX_NUM_STR "\n" |
4710 | printf("Number of vars = %lu\n", BC_MAX_VARS); | 4751 | "MAX Exponent = "BC_MAX_EXP_STR "\n" |
4752 | "Number of vars = "BC_MAX_VARS_STR "\n" | ||
4753 | ); | ||
4711 | break; | 4754 | break; |
4712 | } | 4755 | } |
4713 | 4756 | ||
@@ -5903,12 +5946,12 @@ static BcStatus bc_program_assign(char inst) | |||
5903 | 5946 | ||
5904 | if (ib || sc || left->t == BC_RESULT_OBASE) { | 5947 | if (ib || sc || left->t == BC_RESULT_OBASE) { |
5905 | static const char *const msg[] = { | 5948 | static const char *const msg[] = { |
5906 | "bad ibase; must be [2, 16]", //BC_RESULT_IBASE | 5949 | "bad ibase; must be [2,16]", //BC_RESULT_IBASE |
5907 | "bad scale; must be [0, BC_SCALE_MAX]", //BC_RESULT_SCALE | 5950 | "bad scale; must be [0,"BC_MAX_SCALE_STR"]", //BC_RESULT_SCALE |
5908 | NULL, //can't happen //BC_RESULT_LAST | 5951 | NULL, //can't happen //BC_RESULT_LAST |
5909 | NULL, //can't happen //BC_RESULT_CONSTANT | 5952 | NULL, //can't happen //BC_RESULT_CONSTANT |
5910 | NULL, //can't happen //BC_RESULT_ONE | 5953 | NULL, //can't happen //BC_RESULT_ONE |
5911 | "bad obase; must be [2, BC_BASE_MAX]", //BC_RESULT_OBASE | 5954 | "bad obase; must be [2,"BC_MAX_OBASE_STR"]", //BC_RESULT_OBASE |
5912 | }; | 5955 | }; |
5913 | size_t *ptr; | 5956 | size_t *ptr; |
5914 | unsigned long val, max; | 5957 | unsigned long val, max; |
@@ -6020,7 +6063,7 @@ static BcStatus bc_program_pushArray(char *code, size_t *bgn, | |||
6020 | if (s) goto err; | 6063 | if (s) goto err; |
6021 | 6064 | ||
6022 | if (temp > BC_MAX_DIM) { | 6065 | if (temp > BC_MAX_DIM) { |
6023 | s = bc_error("array too long; must be [1, BC_DIM_MAX]"); | 6066 | s = bc_error("array too long; must be [1,"BC_MAX_DIM_STR"]"); |
6024 | goto err; | 6067 | goto err; |
6025 | } | 6068 | } |
6026 | 6069 | ||