glcpp: Flag invalid pastes for integer followed by non-digits
[mesa.git] / src / glsl / glcpp / glcpp-parse.y
index 5b322fa14c04c2703394d213085b5fa9c07c4ec6..8f17d0d8ab3196c471238dae79ad026c001e9520 100644 (file)
@@ -1057,16 +1057,23 @@ _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
        /* Two string-valued tokens can usually just be mashed
         * together.
         *
-        * XXX: This isn't actually legitimate. Several things here
-        * should result in a diagnostic since the result cannot be a
-        * valid, single pre-processing token. For example, pasting
-        * "123" and "abc" is not legal, but we don't catch that
-        * here. */
+        * There are some exceptions here. Notably, if the first token
+        * is a string representing an integer, then the second token
+        * must also be a an integer and must begin with a digit.
+        */
        if ((token->type == IDENTIFIER || token->type == OTHER || token->type == INTEGER_STRING) &&
            (other->type == IDENTIFIER || other->type == OTHER || other->type == INTEGER_STRING))
        {
                char *str;
 
+               if (token->type == INTEGER_STRING) {
+                       if (other->type != INTEGER_STRING)
+                               goto FAIL;
+                       if (other->value.str[0] < '0' ||
+                           other->value.str[0] > '9')
+                               goto FAIL;
+               }
+
                str = ralloc_asprintf (token, "%s%s", token->value.str,
                                       other->value.str);
                combined = _token_create_str (token, token->type, str);
@@ -1074,6 +1081,7 @@ _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
                return combined;
        }
 
+    FAIL:
        glcpp_error (&token->location, parser, "");
        ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
        _token_print (&parser->info_log, &parser->info_log_length, token);
@@ -1300,18 +1308,30 @@ _arguments_parse (argument_list_t *arguments,
 }
 
 static token_list_t *
-_token_list_create_with_one_space (void *ctx)
+_token_list_create_with_one_ival (void *ctx, int type, int ival)
 {
        token_list_t *list;
-       token_t *space;
+       token_t *node;
 
        list = _token_list_create (ctx);
-       space = _token_create_ival (list, SPACE, SPACE);
-       _token_list_append (list, space);
+       node = _token_create_ival (list, type, ival);
+       _token_list_append (list, node);
 
        return list;
 }
 
+static token_list_t *
+_token_list_create_with_one_space (void *ctx)
+{
+       return _token_list_create_with_one_ival (ctx, SPACE, SPACE);
+}
+
+static token_list_t *
+_token_list_create_with_one_integer (void *ctx, int ival)
+{
+       return _token_list_create_with_one_ival (ctx, INTEGER, ival);
+}
+
 /* Perform macro expansion on 'list', placing the resulting tokens
  * into a new list which is initialized with a first token of type
  * 'head_token_type'. Then begin lexing from the resulting list,
@@ -1533,29 +1553,11 @@ _glcpp_parser_expand_node (glcpp_parser_t *parser,
 
        /* Special handling for __LINE__ and __FILE__, (not through
         * the hash table). */
-       if (strcmp(identifier, "__LINE__") == 0) {
-               token_list_t *replacement;
-               token_t *value;
-
-               replacement = _token_list_create (parser);
-               value = _token_create_ival (parser, INTEGER,
-                                           node->token->location.first_line);
-               _token_list_append (replacement, value);
-
-               return replacement;
-       }
+       if (strcmp(identifier, "__LINE__") == 0)
+               return _token_list_create_with_one_integer (parser, node->token->location.first_line);
 
-       if (strcmp(identifier, "__FILE__") == 0) {
-               token_list_t *replacement;
-               token_t *value;
-
-               replacement = _token_list_create (parser);
-               value = _token_create_ival (parser, INTEGER,
-                                           node->token->location.source);
-               _token_list_append (replacement, value);
-
-               return replacement;
-       }
+       if (strcmp(identifier, "__FILE__") == 0)
+               return _token_list_create_with_one_integer (parser, node->token->location.source);
 
        /* Look up this identifier in the hash table. */
        macro = hash_table_find (parser->defines, identifier);