vkd3d-shader/hlsl: Handle over/underflow when parsing integer literals.

Signed-off-by: Matteo Bruni <mbruni@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Giovanni Mascellani <gmascellani@codeweavers.com>
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Matteo Bruni 2022-05-11 16:39:08 +02:00 committed by Alexandre Julliard
parent a9dc39dd92
commit 228f7ab5cd
4 changed files with 38 additions and 36 deletions

View File

@ -197,15 +197,15 @@ row_major {return KW_ROW_MAJOR; }
return C_FLOAT; return C_FLOAT;
} }
0x[0-9a-fA-F]+ { 0x[0-9a-fA-F]+ {
sscanf(yytext, "0x%x", &yylval->intval); yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER; return C_INTEGER;
} }
0[0-7]+ { 0[0-7]+ {
sscanf(yytext, "0%o", &yylval->intval); yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER; return C_INTEGER;
} }
[0-9]+ { [0-9]+ {
yylval->intval = (atoi(yytext)); yylval->intval = vkd3d_parse_integer(yytext);
return C_INTEGER; return C_INTEGER;
} }

View File

@ -165,38 +165,6 @@ static bool preproc_push_if(struct preproc_ctx *ctx, bool condition)
return true; return true;
} }
static int char_to_int(char c)
{
if ('0' <= c && c <= '9')
return c - '0';
if ('A' <= c && c <= 'F')
return c - 'A' + 10;
if ('a' <= c && c <= 'f')
return c - 'a' + 10;
return -1;
}
static uint32_t preproc_parse_integer(const char *s)
{
uint32_t base = 10, ret = 0;
int digit;
if (*s == '0')
{
base = 8;
++s;
if (*s == 'x' || *s == 'X')
{
base = 16;
++s;
}
}
while ((digit = char_to_int(*s++)) >= 0)
ret = ret * base + (uint32_t)digit;
return ret;
}
static int default_open_include(const char *filename, bool local, static int default_open_include(const char *filename, bool local,
const char *parent_data, void *context, struct vkd3d_shader_code *out) const char *parent_data, void *context, struct vkd3d_shader_code *out)
{ {
@ -691,7 +659,7 @@ directive
primary_expr primary_expr
: T_INTEGER : T_INTEGER
{ {
$$ = preproc_parse_integer($1); $$ = vkd3d_parse_integer($1);
vkd3d_free($1); vkd3d_free($1);
} }
| T_IDENTIFIER | T_IDENTIFIER

View File

@ -24,6 +24,38 @@
VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG");
static inline int char_to_int(char c)
{
if ('0' <= c && c <= '9')
return c - '0';
if ('A' <= c && c <= 'F')
return c - 'A' + 10;
if ('a' <= c && c <= 'f')
return c - 'a' + 10;
return -1;
}
uint32_t vkd3d_parse_integer(const char *s)
{
uint32_t base = 10, ret = 0;
int digit;
if (*s == '0')
{
base = 8;
++s;
if (*s == 'x' || *s == 'X')
{
base = 16;
++s;
}
}
while ((digit = char_to_int(*s++)) >= 0)
ret = ret * base + (uint32_t)digit;
return ret;
}
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
{ {
buffer->buffer_size = 16; buffer->buffer_size = 16;

View File

@ -1035,6 +1035,8 @@ static inline size_t bytecode_get_size(struct vkd3d_bytecode_buffer *buffer)
return buffer->size; return buffer->size;
} }
uint32_t vkd3d_parse_integer(const char *s);
struct vkd3d_shader_message_context struct vkd3d_shader_message_context
{ {
enum vkd3d_shader_log_level log_level; enum vkd3d_shader_log_level log_level;