@@ -3778,27 +3778,52 @@ MIMEHdrImpl::recompute_cooked_stuff(MIMEField *changing_field_or_null)
37783778 if (mask & (MIME_COOKED_MASK_CC_MAX_AGE | MIME_COOKED_MASK_CC_S_MAXAGE | MIME_COOKED_MASK_CC_MAX_STALE |
37793779 MIME_COOKED_MASK_CC_MIN_FRESH)) {
37803780 int value;
3781+ // Per RFC 7230 Section 3.2.3, there should be no whitespace around '='.
3782+ const char *value_start = c;
37813783
3782- if (mime_parse_integer (c, e, &value)) {
3784+ // Check if the next character is '=' (no space allowed before '=').
3785+ if (c < e && *c == ' =' ) {
3786+ ++c; // Move past the '='
3787+
3788+ // Again: no whitespace after the '=' either. Keep in mind that values can be negative.
3789+ bool valid_syntax = (c < e) && (is_digit (*c) || *c == ' -' );
3790+
3791+ if (valid_syntax) {
3792+ // Reset to value_start to let mime_parse_integer do its work.
3793+ c = value_start;
3794+ if (mime_parse_integer (c, e, &value)) {
37833795#if TRACK_COOKING
3784- Dbg (dbg_ctl_http, " set integer value %d" , value);
3796+ Dbg (dbg_ctl_http, " set integer value %d" , value);
37853797#endif
3786- if (token_wks == MIME_VALUE_MAX_AGE.c_str ()) {
3787- m_cooked_stuff.m_cache_control .m_secs_max_age = value;
3788- } else if (token_wks == MIME_VALUE_MIN_FRESH.c_str ()) {
3789- m_cooked_stuff.m_cache_control .m_secs_min_fresh = value;
3790- } else if (token_wks == MIME_VALUE_MAX_STALE.c_str ()) {
3791- m_cooked_stuff.m_cache_control .m_secs_max_stale = value;
3792- } else if (token_wks == MIME_VALUE_S_MAXAGE.c_str ()) {
3793- m_cooked_stuff.m_cache_control .m_secs_s_maxage = value;
3794- }
3795- } else {
3798+ if (token_wks == MIME_VALUE_MAX_AGE.c_str ()) {
3799+ m_cooked_stuff.m_cache_control .m_secs_max_age = value;
3800+ } else if (token_wks == MIME_VALUE_MIN_FRESH.c_str ()) {
3801+ m_cooked_stuff.m_cache_control .m_secs_min_fresh = value;
3802+ } else if (token_wks == MIME_VALUE_MAX_STALE.c_str ()) {
3803+ m_cooked_stuff.m_cache_control .m_secs_max_stale = value;
3804+ } else if (token_wks == MIME_VALUE_S_MAXAGE.c_str ()) {
3805+ m_cooked_stuff.m_cache_control .m_secs_s_maxage = value;
3806+ }
3807+ } else {
37963808#if TRACK_COOKING
3797- Dbg (dbg_ctl_http, " set integer value %d" , INT_MAX);
3809+ Dbg (dbg_ctl_http, " set integer value %d" , INT_MAX);
37983810#endif
3799- if (token_wks == MIME_VALUE_MAX_STALE.c_str ()) {
3800- m_cooked_stuff.m_cache_control .m_secs_max_stale = INT_MAX;
3811+ if (token_wks == MIME_VALUE_MAX_STALE.c_str ()) {
3812+ m_cooked_stuff.m_cache_control .m_secs_max_stale = INT_MAX;
3813+ }
3814+ }
3815+ } else {
3816+ // Syntax is malformed (e.g., whitespace after '=', quotes around value, or no value).
3817+ // Treat this as unrecognized and clear the mask.
3818+ csv_value_mask = 0 ;
3819+ m_cooked_stuff.m_cache_control .m_mask &= ~mask;
38013820 }
3821+ } else {
3822+ // No '=' found, or whitespace before '='. This is malformed.
3823+ // For directives that require values, this is an error.
3824+ // Clear the mask for this directive.
3825+ csv_value_mask = 0 ;
3826+ m_cooked_stuff.m_cache_control .m_mask &= ~mask;
38023827 }
38033828 }
38043829
0 commit comments