--- parser3/src/classes/math.C 2010/10/13 11:30:08 1.57 +++ parser3/src/classes/math.C 2012/05/23 20:51:40 1.60 @@ -1,15 +1,13 @@ /** @file Parser: @b math parser class. - Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) + Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) portions from gen_uuid.c, Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. */ -static const char * const IDENT_MATH_C="$Date: 2010/10/13 11:30:08 $"; - #include "pa_vmethod_frame.h" #include "pa_common.h" #include "pa_vint.h" @@ -32,6 +30,8 @@ static const char * const IDENT_MATH_C=" extern char *crypt(const char* , const char* ); #endif +volatile const char * IDENT_MATH_C="$Id: math.C,v 1.60 2012/05/23 20:51:40 moko Exp $"; + // defines #define MAX_SALT 8 @@ -357,38 +357,55 @@ static void _crc32(Request& r, MethodPar r.write_no_lang(*new VInt(pa_crc32(string, strlen(string)))); } -static void toBase(long value, int base, char*& ptr){ +static void toBase(unsigned long value, unsigned int base, char*& ptr){ static const char* hex="0123456789ABCDEF"; int rest = value % base; - if(value > base) + if(value >= base) toBase( (value-rest)/base, base, ptr); *ptr++=(char)hex[rest]; } static void _convert(Request& r, MethodParams& params) { - const char *string=params.as_string(0, PARAMETER_MUST_BE_STRING).cstr(); + const char *str=params.as_string(0, PARAMETER_MUST_BE_STRING).cstr(); + int base_from=params.as_int(1, "base from must be integer", r); if(base_from < 2 || base_from > 16) throw Exception(PARSER_RUNTIME, 0, "base from must be an integer from 2 to 16"); - char *error_pos; - long value=strtol(string, &error_pos, base_from); - while(char c=*error_pos++) - if(!isspace((unsigned char)c)) - throw Exception("number.format", - 0, - "'%s' is invalid number (int)", string); - int base_to=params.as_int(2, "base to must be integer", r); if(base_to < 2 || base_to > 16) throw Exception(PARSER_RUNTIME, 0, "base to must be an integer from 2 to 16"); - char result_cstr[sizeof(long)*8+1/*minus for negative number*/+1/*terminator*/]; - char* ptr=(char *)&result_cstr; - if(value < 0){ - *ptr++='-'; - value=-value; + while(*str && isspace((unsigned char)*str)) + str++; + + if(!*str) + return; + + char *error_pos; + + bool negative=false; + if(str[0]=='-') { + negative=true; + str++; + } else if(str[0]=='+') { + str++; } + + errno=0; + unsigned long value=strtoul(str, &error_pos, base_from); + if(errno==ERANGE) + throw Exception("number.format", 0, "'%s' is out of range (int)", str); + + while(char c=*error_pos++) + if(!isspace((unsigned char)c)) + throw Exception("number.format", 0, "'%s' is invalid number (int)", str); + + char result_cstr[sizeof(unsigned long)*8+1/*minus for negative number*/+1/*terminator*/]; + char* ptr=result_cstr; + if(negative) + *ptr++='-'; + toBase(value, base_to, ptr); *ptr=0; r.write_pass_lang(*new String(pa_strdup(result_cstr)));