glfw: hot patch undefined behavior in GLFW that went unnoticed 6+ years

Upstream pull request: https://github.com/glfw/glfw/pull/1986

Article: https://devlog.hexops.com/2021/perfecting-glfw-for-zig-and-finding-undefined-behavior

Fixes hexops/mach#20

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2021-10-31 11:50:09 -07:00
parent 93110e82ca
commit 9bc9984930
2 changed files with 33 additions and 34 deletions

View file

@ -2194,39 +2194,38 @@ test "setTitle" {
try window.setTitle("Updated title!");
}
// TODO(window): test appears to fail on at least Linux, image size is potentially wrong.
// test "setIcon" {
// const allocator = testing.allocator;
// const glfw = @import("main.zig");
// try glfw.init();
// defer glfw.terminate();
test "setIcon" {
const allocator = testing.allocator;
const glfw = @import("main.zig");
try glfw.init();
defer glfw.terminate();
// const window = glfw.Window.create(640, 480, "Hello, Zig!", null, null) catch |err| {
// // return without fail, because most of our CI environments are headless / we cannot open
// // windows on them.
// std.debug.print("note: failed to create window: {}\n", .{err});
// return;
// };
// defer window.destroy();
const window = glfw.Window.create(640, 480, "Hello, Zig!", null, null) catch |err| {
// return without fail, because most of our CI environments are headless / we cannot open
// windows on them.
std.debug.print("note: failed to create window: {}\n", .{err});
return;
};
defer window.destroy();
// // Create an all-red icon image.
// var width: usize = 48;
// var height: usize = 48;
// const icon = try Image.init(allocator, width, height, width * height * 4);
// var x: usize = 0;
// var y: usize = 0;
// while (y <= height) : (y += 1) {
// while (x <= width) : (x += 1) {
// icon.pixels[(x * y * 4) + 0] = 255; // red
// icon.pixels[(x * y * 4) + 1] = 0; // green
// icon.pixels[(x * y * 4) + 2] = 0; // blue
// icon.pixels[(x * y * 4) + 3] = 255; // alpha
// }
// }
// window.setIcon(allocator, &[_]Image{icon}) catch |err| std.debug.print("can't set window icon, wayland maybe? error={}\n", .{err});
// Create an all-red icon image.
var width: usize = 48;
var height: usize = 48;
const icon = try Image.init(allocator, width, height, width * height * 4);
var x: usize = 0;
var y: usize = 0;
while (y <= height) : (y += 1) {
while (x <= width) : (x += 1) {
icon.pixels[(x * y * 4) + 0] = 255; // red
icon.pixels[(x * y * 4) + 1] = 0; // green
icon.pixels[(x * y * 4) + 2] = 0; // blue
icon.pixels[(x * y * 4) + 3] = 255; // alpha
}
}
window.setIcon(allocator, &[_]Image{icon}) catch |err| std.debug.print("can't set window icon, wayland maybe? error={}\n", .{err});
// icon.deinit(allocator); // glfw copies it.
// }
icon.deinit(allocator); // glfw copies it.
}
test "getPos" {
const glfw = @import("main.zig");

View file

@ -2133,10 +2133,10 @@ void _glfwPlatformSetWindowIcon(_GLFWwindow* window,
for (j = 0; j < images[i].width * images[i].height; j++)
{
*target++ = (images[i].pixels[j * 4 + 0] << 16) |
(images[i].pixels[j * 4 + 1] << 8) |
(images[i].pixels[j * 4 + 2] << 0) |
(images[i].pixels[j * 4 + 3] << 24);
*target++ = (((long)images[i].pixels[j * 4 + 0]) << 16) |
(((long)images[i].pixels[j * 4 + 1]) << 8) |
(((long)images[i].pixels[j * 4 + 2]) << 0) |
(((long)images[i].pixels[j * 4 + 3]) << 24);
}
}