mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 01:20:17 +01:00
glcpp: Handle '#version 0' and other invalid values
The #version directive can only handle decimal constants. Enforce that
the value is a decimal constant.
Section 3.3 (Preprocessor) of the GLSL 4.50 spec says:
The language version a shader is written to is specified by
#version number profile opt
where number must be a version of the language, following the same
convention as __VERSION__ above.
The same section also says:
__VERSION__ will substitute a decimal integer reflecting the version
number of the OpenGL shading language.
Use a separate flag to track whether or not the #version line has been
encountered. Any possible sentinel (0 is currently used) could be
specified in a #version directive. This would lead to trying to
(internally) redefine __VERSION__. Since there is no parser location
for this addition, NULL is passed. This eventually results in a NULL
dereference and a segfault.
Attempts to use -1 as the sentinel would also fail if '#version
4294967295' or '#version 18446744073709551615' were used. We should
have piglit tests for both of these.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97420
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
Cc: mesa-stable@lists.freedesktop.org
Cc: Juan A. Suarez Romero <jasuarez@igalia.com>
Cc: Karol Herbst <karolherbst@gmail.com>
This commit is contained in:
parent
cbba5e13ac
commit
e85a747e29
2 changed files with 28 additions and 6 deletions
|
|
@ -177,7 +177,7 @@ add_builtin_define(glcpp_parser_t *parser, const char *name, int value);
|
|||
* (such as the <HASH> and <DEFINE> start conditions in the lexer). */
|
||||
%token DEFINED ELIF_EXPANDED HASH_TOKEN DEFINE_TOKEN FUNC_IDENTIFIER OBJ_IDENTIFIER ELIF ELSE ENDIF ERROR_TOKEN IF IFDEF IFNDEF LINE PRAGMA UNDEF VERSION_TOKEN GARBAGE IDENTIFIER IF_EXPANDED INTEGER INTEGER_STRING LINE_EXPANDED NEWLINE OTHER PLACEHOLDER SPACE PLUS_PLUS MINUS_MINUS
|
||||
%token PASTE
|
||||
%type <ival> INTEGER operator SPACE integer_constant
|
||||
%type <ival> INTEGER operator SPACE integer_constant version_constant
|
||||
%type <expression_value> expression
|
||||
%type <str> IDENTIFIER FUNC_IDENTIFIER OBJ_IDENTIFIER INTEGER_STRING OTHER ERROR_TOKEN PRAGMA
|
||||
%type <string_list> identifier_list
|
||||
|
|
@ -419,14 +419,14 @@ control_line_success:
|
|||
| HASH_TOKEN ENDIF {
|
||||
_glcpp_parser_skip_stack_pop (parser, & @1);
|
||||
} NEWLINE
|
||||
| HASH_TOKEN VERSION_TOKEN integer_constant NEWLINE {
|
||||
if (parser->version != 0) {
|
||||
| HASH_TOKEN VERSION_TOKEN version_constant NEWLINE {
|
||||
if (parser->version_set) {
|
||||
glcpp_error(& @1, parser, "#version must appear on the first line");
|
||||
}
|
||||
_glcpp_parser_handle_version_declaration(parser, $3, NULL, true);
|
||||
}
|
||||
| HASH_TOKEN VERSION_TOKEN integer_constant IDENTIFIER NEWLINE {
|
||||
if (parser->version != 0) {
|
||||
| HASH_TOKEN VERSION_TOKEN version_constant IDENTIFIER NEWLINE {
|
||||
if (parser->version_set) {
|
||||
glcpp_error(& @1, parser, "#version must appear on the first line");
|
||||
}
|
||||
_glcpp_parser_handle_version_declaration(parser, $3, $4, true);
|
||||
|
|
@ -465,6 +465,17 @@ integer_constant:
|
|||
$$ = $1;
|
||||
}
|
||||
|
||||
version_constant:
|
||||
INTEGER_STRING {
|
||||
/* Both octal and hexadecimal constants begin with 0. */
|
||||
if ($1[0] == '0' && $1[1] != '\0') {
|
||||
glcpp_error(&@1, parser, "invalid #version \"%s\" (not a decimal constant)", $1);
|
||||
$$ = 0;
|
||||
} else {
|
||||
$$ = strtoll($1, NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
expression:
|
||||
integer_constant {
|
||||
$$.value = $1;
|
||||
|
|
@ -1361,6 +1372,7 @@ glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api
|
|||
parser->state = state;
|
||||
parser->api = api;
|
||||
parser->version = 0;
|
||||
parser->version_set = false;
|
||||
|
||||
parser->has_new_line_number = 0;
|
||||
parser->new_line_number = 1;
|
||||
|
|
@ -2293,10 +2305,11 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
|
|||
const char *es_identifier,
|
||||
bool explicitly_set)
|
||||
{
|
||||
if (parser->version != 0)
|
||||
if (parser->version_set)
|
||||
return;
|
||||
|
||||
parser->version = version;
|
||||
parser->version_set = true;
|
||||
|
||||
add_builtin_define (parser, "__VERSION__", version);
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,15 @@ struct glcpp_parser {
|
|||
void *state;
|
||||
gl_api api;
|
||||
unsigned version;
|
||||
|
||||
/**
|
||||
* Has the #version been set?
|
||||
*
|
||||
* A separate flag is used because any possible sentinel value in
|
||||
* \c ::version could also be set by a #version line.
|
||||
*/
|
||||
bool version_set;
|
||||
|
||||
bool has_new_line_number;
|
||||
int new_line_number;
|
||||
bool has_new_source_number;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue