mesa: add helper to validate tokenise shader include path
authorTimothy Arceri <tarceri@itsqueeze.com>
Fri, 23 Aug 2019 04:33:41 +0000 (14:33 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Wed, 20 Nov 2019 05:05:55 +0000 (05:05 +0000)
Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Reviewed-by: Witold Baryluk <witold.baryluk@gmail.com>
src/mesa/main/shaderapi.c

index 760d046dcdeb73cb34446e9a20012dca284bc9de..c7f5ac797e77593e088f256e70655be8ca5bb9db 100644 (file)
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <stdbool.h>
 #include <c99_alloca.h>
+
 #include "main/glheader.h"
 #include "main/context.h"
 #include "main/enums.h"
@@ -61,6 +62,7 @@
 #include "util/mesa-sha1.h"
 #include "util/crc32.h"
 #include "util/os_file.h"
+#include "util/simple_list.h"
 
 /**
  * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
@@ -3193,6 +3195,86 @@ _mesa_destroy_shader_includes(struct gl_shared_state *shared)
    free(shared->ShaderIncludes);
 }
 
+static bool
+valid_path_format(const char *str)
+{
+   int i = 0;
+
+   if (!str[i] || str[i] != '/')
+      return false;
+
+   i++;
+
+   while (str[i]) {
+      const char c = str[i++];
+      if (('A' <= c && c <= 'Z') ||
+          ('a' <= c && c <= 'z') ||
+          ('0' <= c && c <= '9'))
+         continue;
+
+      if (c == '/') {
+         if (str[i - 2] == '/')
+            return false;
+
+         continue;
+      }
+
+      if (strchr("^. _+*%[](){}|&~=!:;,?-", c) == NULL)
+         return false;
+  }
+
+  if (str[i - 1] == '/')
+     return false;
+
+  return true;
+}
+
+
+static bool
+validate_and_tokenise_sh_incl(struct gl_context *ctx,
+                              void *mem_ctx,
+                              struct sh_incl_path_entry **path_list,
+                              char *full_path)
+{
+   if (!valid_path_format(full_path)) {
+       _mesa_error(ctx, GL_INVALID_VALUE,
+                   "glNamedStringARB(invalid name %s)", full_path);
+      return false;
+   }
+
+   char *save_ptr = NULL;
+   char *path_str = strtok_r(full_path, "/", &save_ptr);
+
+   *path_list = rzalloc(mem_ctx, struct sh_incl_path_entry);
+
+   make_empty_list(*path_list);
+
+   while (path_str != NULL) {
+      if (strlen(path_str) == 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glNamedStringARB(invalid name %s)", full_path);
+         return false;
+      }
+
+      if (strcmp(path_str, ".") == 0) {
+         /* Do nothing */
+      } else if (strcmp(path_str, "..") == 0) {
+         struct sh_incl_path_entry *last = last_elem(*path_list);
+         remove_from_list(last);
+      } else {
+         struct sh_incl_path_entry *path =
+            rzalloc(mem_ctx, struct sh_incl_path_entry);
+
+         path->path = strdup(path_str);
+         insert_at_tail(*path_list, path);
+      }
+
+      path_str = strtok_r(NULL, "/", &save_ptr);
+   }
+
+   return true;
+}
+
 GLvoid GLAPIENTRY
 _mesa_NamedStringARB(GLenum type, GLint namelen, const GLchar *name,
                      GLint stringlen, const GLchar *string)