diff --git a/src/cpp.c b/src/cpp.c index 01715a6d1001676c3e215c3a61cb4cd696c174bb..2dc2891a3bc2223abc0bf189bd7d108c4b618ce6 100644 --- a/src/cpp.c +++ b/src/cpp.c @@ -1314,13 +1314,6 @@ static ptrdiff_t find_end_of_char( struct cpp *this, const PCHARP data, ptrdiff_ cpp_error(this,"End of file in character constant."); break; } - - if(e++>32) - { - cpp_error(this,"Too long character constant."); - break; - } - switch(INDEX_PCHARP(data,pos++)) { case '\n': diff --git a/src/lexer.h b/src/lexer.h index 4a588369c13cdb48fbb841ea920a7841996cc2b0..57f1bf22d6fb987870cbe0087e19b3d2a08b88c9 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -842,8 +842,10 @@ unknown_directive: case '\'': { - int l = 0; - INT_TYPE res = 0; + unsigned int l = 0; + struct svalue res = svalue_int_zero; + MP_INT bigint; + while(1) { INT32 tmp; @@ -858,16 +860,24 @@ unknown_directive: tmp = char_const(lex); /* fallthrough. */ default: - res <<= 8; - res |= tmp; - if( ++l > 4 ) + l++; + if( l == sizeof(INT_TYPE)-1 ) + { + /* overflow possible. Switch to bignums. */ + mpz_init(&bigint); + mpz_set_ui(&bigint,res.u.integer); + TYPEOF(res) = PIKE_T_OBJECT; + } + + if( l >= sizeof(INT_TYPE)-1 ) { - yyerror("Too large character constant."); - /* skip the rest of the characters. */ - do - tmp = GETC(); - while( tmp && (tmp != '\'') ); - goto return_char; + mpz_mul_2exp(&bigint,&bigint,8); + mpz_add_ui(&bigint,&bigint,tmp); + } + else + { + res.u.integer <<= 8; + res.u.integer |= tmp; } break; @@ -878,7 +888,15 @@ unknown_directive: } } return_char: - debug_malloc_pass( yylval->n=mkintnode(res) ); + if( TYPEOF(res) == PIKE_T_OBJECT ) + { + push_bignum( &bigint ); + mpz_clear(&bigint); + reduce_stack_top_bignum(); + res = *--Pike_sp; + } + debug_malloc_pass( yylval->n=mksvaluenode(&res) ); + free_svalue( &res ); return TOK_NUMBER; } /* notreached. */