Browse Source

GPU: Compile Metal shader source from NSString

Using the @() syntax to construct an NSString assumes the parenthesized
pointer is null-terminated, but the Metal shader source included in
render/sdlgpu/shaders/metal.h is not null-terminated.

Quoting the clang documentation on Objective-C literals:

    When the type of the parenthesized expression is (char *) or (const
    char *), the result of the boxed expression is a pointer to an
    NSString object containing equivalent character data, which is
    assumed to be ‘\0’-terminated and UTF-8 encoded.

Because the @() syntax assumes null-termination, it may read garbage
data after the shader source (up to the next null byte), which can then
cause the Metal shader compiler to fail. To prevent this, instead of
using the @() boxing syntax, we explicitly construct an NSString using
the string length passed by the caller.
Davis Gallinghouse 7 months ago
parent
commit
deb313dd99
1 changed files with 5 additions and 1 deletions
  1. 5 1
      src/gpu/metal/SDL_gpu_metal.m

+ 5 - 1
src/gpu/metal/SDL_gpu_metal.m

@@ -740,8 +740,12 @@ static MetalLibraryFunction METAL_INTERNAL_CompileShader(
     id<MTLFunction> function;
 
     if (format == SDL_GPU_SHADERFORMAT_MSL) {
+        NSString *codeString = [[NSString alloc]
+            initWithBytes:code
+                   length:codeSize
+                 encoding:NSUTF8StringEncoding];
         library = [renderer->device
-            newLibraryWithSource:@((const char *)code)
+            newLibraryWithSource:codeString
                          options:nil
                            error:&error];
     } else if (format == SDL_GPU_SHADERFORMAT_METALLIB) {