X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=src%2Fdoprnt.c;h=8076a6b47fc515bf6b6ad560e94de346e44b75c2;hb=78dd9663a9a07a0572e1e286dfea557c6f5be826;hp=37a19f331b0538b6f5d3dd21604117b4c2931475;hpb=c879e5b17b3d5fef34ab58fc66e1cbb4269e5bb4;p=sxemacs diff --git a/src/doprnt.c b/src/doprnt.c index 37a19f3..8076a6b 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -397,6 +397,10 @@ get_doprnt_args(printf_spec_dynarr *specs, va_list vargs) printf_arg_t arg; REGISTER int i; int args_needed = get_args_needed(specs); + int spec_len = -1; + + if (specs) + spec_len = Dynarr_length(specs); xzero(arg); for (i = 1; i <= args_needed; i++) { @@ -404,14 +408,14 @@ get_doprnt_args(printf_spec_dynarr *specs, va_list vargs) char ch; printf_spec_t spec = 0; - for (j = 0; j < Dynarr_length(specs); j++) { + for (j = 0; j < spec_len; j++) { spec = Dynarr_atp(specs, j); if (spec->argnum == i) { break; } } - if (j == Dynarr_length(specs)) + if (j >= spec_len) error("No conversion spec for argument %d", i); ch = spec->converter; @@ -527,10 +531,10 @@ __nnaughts(printf_spec_t s, int nlen, int tlen) } static inline int -__bsize_smZ(printf_spec_t s, EMACS_INT UNUSED(Z)) +__bsize_smZ(printf_spec_t s, EMACS_INT SXE_UNUSED(Z)) __attribute__((always_inline)); static inline int -__bsize_smZ(printf_spec_t s, EMACS_INT UNUSED(Z)) +__bsize_smZ(printf_spec_t s, EMACS_INT SXE_UNUSED(Z)) { return 32 + s->minwidth + sizeof(long int) * /* if binary representation is wanted, use an @@ -743,7 +747,7 @@ emacs_doprnt_smZ(Lisp_Object stream, EMACS_INT Z, printf_spec_t s, char ch) } else /* ch == 'b' */ { text_len = __ulong_to_bit_string(text, Z); } - + assert(text_len >= 0 && text_len < alloc_sz); /* postprocess, move stuff around, insert naughts, etc. */ text_len = __postproc2(s, text, text_len, alloc_sz); @@ -961,6 +965,7 @@ emacs_doprnt_number(Lisp_Object stream, char *p = constructed_spec; int length, alloca_sz = max_float_print_size; int min = spec->minwidth, prec = spec->precision; + int max_spec = sizeof(constructed_spec); #if 0 /* absolute non-sense :O ... @@ -996,20 +1001,27 @@ emacs_doprnt_number(Lisp_Object stream, *p++ = '0'; if (spec->minwidth >= 0) { - long_to_string(p, spec->minwidth); + long_to_string(p, spec->minwidth, max_spec); + max_spec -= strlen(p); p += strlen (p); } if (spec->precision >= 0) { *p++ = '.'; - long_to_string(p, spec->precision); + --max_spec; + long_to_string(p, spec->precision, max_spec); + max_spec -= strlen(p); p += strlen (p); } #if fpfloat_long_double_p *p++ = 'L'; + --max_spec; #endif *p++ = ch; + --max_spec; *p++ = '\0'; + --max_spec; + assert(max_spec >= 0); if (NILP(obj)) length = snprintf(text_to_print, alloca_sz, constructed_spec, arg.d); @@ -1017,9 +1029,10 @@ emacs_doprnt_number(Lisp_Object stream, length = snprintf(text_to_print, alloca_sz, constructed_spec, XFLOAT_DATA(obj)); - if (length > alloca_sz) + if (length > alloca_sz) { + /* should we really silently truncate?! */ length = alloca_sz; - + } doprnt_1(stream, (Bufbyte *)text_to_print, length, 0, -1, 0, 0); return; @@ -1319,8 +1332,8 @@ emacs_doprnt_1(Lisp_Object stream, const Bufbyte * format_nonreloc, } else { args = get_doprnt_args(specs, vargs); } - - for (i = 0; i < Dynarr_length(specs); i++) { + + for (i = 0; specs && i < Dynarr_length(specs); i++) { printf_spec_t spec = Dynarr_atp(specs, i); char ch; @@ -1345,26 +1358,30 @@ emacs_doprnt_1(Lisp_Object stream, const Bufbyte * format_nonreloc, was specified as an argument. Extract the data and forward it to the next spec, to which it will apply. */ if (ch == '*') { - printf_spec_t nextspec = Dynarr_atp(specs, i + 1); - Lisp_Object obj = largs[spec->argnum - 1]; - - if (INTP(obj)) { - if (spec->forwarding_precision) { - nextspec->precision = XINT(obj); - nextspec->minwidth = spec->minwidth; - } else { - nextspec->minwidth = XINT(obj); - if (XINT(obj) < 0) { - spec->minus_flag = 1; - nextspec->minwidth = - -nextspec->minwidth; + if(!largs) { + error("Invalid largs and '*' converter in emacs_doprnt_1"); + } else { + printf_spec_t nextspec = Dynarr_atp(specs, i + 1); + Lisp_Object obj = largs[spec->argnum - 1]; + + if (INTP(obj)) { + if (spec->forwarding_precision) { + nextspec->precision = XINT(obj); + nextspec->minwidth = spec->minwidth; + } else { + nextspec->minwidth = XINT(obj); + if (XINT(obj) < 0) { + spec->minus_flag = 1; + nextspec->minwidth = + -nextspec->minwidth; + } } + nextspec->minus_flag = spec->minus_flag; + nextspec->plus_flag = spec->plus_flag; + nextspec->space_flag = spec->space_flag; + nextspec->number_flag = spec->number_flag; + nextspec->zero_flag = spec->zero_flag; } - nextspec->minus_flag = spec->minus_flag; - nextspec->plus_flag = spec->plus_flag; - nextspec->space_flag = spec->space_flag; - nextspec->number_flag = spec->number_flag; - nextspec->zero_flag = spec->zero_flag; } continue; }