| 2620 | */ |
| 2621 | #define CHECK_OVERFLOW(a, b) if (a > b) return APR_EGENERAL |
| 2622 | AP_DECLARE(apr_status_t) ap_timeout_parameter_parse( |
| 2623 | const char *timeout_parameter, |
| 2624 | apr_interval_time_t *timeout, |
| 2625 | const char *default_time_unit) |
| 2626 | { |
| 2627 | char *endp; |
| 2628 | const char *time_str; |
| 2629 | apr_int64_t tout; |
| 2630 | apr_uint64_t check; |
| 2631 | |
| 2632 | tout = apr_strtoi64(timeout_parameter, &endp, 10); |
| 2633 | if (errno) { |
| 2634 | return errno; |
| 2635 | } |
| 2636 | if (!endp || !*endp) { |
| 2637 | time_str = default_time_unit; |
| 2638 | } |
| 2639 | else { |
| 2640 | time_str = endp; |
| 2641 | } |
| 2642 | |
| 2643 | if (tout < 0) { |
| 2644 | return APR_EGENERAL; |
| 2645 | } |
| 2646 | |
| 2647 | switch (*time_str) { |
| 2648 | /* Time is in seconds */ |
| 2649 | case 's': |
| 2650 | CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX)); |
| 2651 | check = apr_time_from_sec(tout); |
| 2652 | break; |
| 2653 | /* Time is in hours */ |
| 2654 | case 'h': |
| 2655 | CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 3600)); |
| 2656 | check = apr_time_from_sec(tout * 3600); |
| 2657 | break; |
| 2658 | case 'm': |
| 2659 | switch (*(++time_str)) { |
| 2660 | /* Time is in milliseconds */ |
| 2661 | case 's': |
| 2662 | CHECK_OVERFLOW(tout, apr_time_as_msec(APR_INT64_MAX)); |
| 2663 | check = apr_time_from_msec(tout); |
| 2664 | break; |
| 2665 | /* Time is in minutes */ |
| 2666 | case 'i': |
| 2667 | CHECK_OVERFLOW(tout, apr_time_sec(APR_INT64_MAX / 60)); |
| 2668 | check = apr_time_from_sec(tout * 60); |
| 2669 | break; |
| 2670 | default: |
| 2671 | return APR_EGENERAL; |
| 2672 | } |
| 2673 | break; |
| 2674 | default: |
| 2675 | return APR_EGENERAL; |
| 2676 | } |
| 2677 | |
| 2678 | *timeout = (apr_interval_time_t)check; |
| 2679 | return APR_SUCCESS; |
no outgoing calls
no test coverage detected