#include <errno.h>
#include <stdbool.h>
#include <c99_alloca.h>
+
#include "main/glheader.h"
#include "main/context.h"
#include "main/enums.h"
#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.
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)