From 2766c70ad3b32f61b6f8f5bbcb2af9cfd38c6cef Mon Sep 17 00:00:00 2001 From: cx384 Date: Sun, 7 Jan 2024 21:49:26 +0100 Subject: [PATCH] Fix dividing by zero crashes in texture modifiers --- src/client/tile.cpp | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 55a34d432..eb055c2ce 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -1598,6 +1598,13 @@ bool TextureSource::generateImagePart(std::string part_of_name, u32 frame_count = stoi(sf.next(":")); u32 frame_index = stoi(sf.next(":")); + if (frame_count == 0){ + errorstream << "generateImagePart(): invalid frame_count " + << "for part_of_name=\"" << part_of_name + << "\", using frame_count = 1 instead." << std::endl; + frame_count = 1; + } + if (baseimg == NULL){ errorstream<<"generateImagePart(): baseimg != NULL " <<"for part_of_name=\""<getDimension(), color); } else { apply_screen(baseimg, v2u32(0, 0), baseimg->getDimension(), color); @@ -1899,6 +1906,13 @@ bool TextureSource::generateImagePart(std::string part_of_name, u32 x0 = stoi(sf.next(",")); u32 y0 = stoi(sf.next(":")); + if (w0 == 0 || h0 == 0) { + errorstream << "generateImagePart(): invalid width or height " + << "for part_of_name=\"" << part_of_name + << "\", cancelling." << std::endl; + return false; + } + core::dimension2d img_dim = baseimg->getDimension(); core::dimension2d tile_dim(v2u32(img_dim) / v2u32(w0, h0)); @@ -1965,7 +1979,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, } /* [hsl:hue:saturation:lightness - or + or [colorizehsl:hue:saturation:lightness Adjust the hue, saturation, and lightness of the base image. Like @@ -1978,7 +1992,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, will be converted to a grayscale image as though seen through a colored glass, like "Colorize" in GIMP. */ - else if (str_starts_with(part_of_name, "[hsl:") || + else if (str_starts_with(part_of_name, "[hsl:") || str_starts_with(part_of_name, "[colorizehsl:")) { if (baseimg == nullptr) { @@ -1995,7 +2009,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, Strfnd sf(part_of_name); sf.next(":"); - s32 hue = mystoi(sf.next(":"), -180, 360); + s32 hue = mystoi(sf.next(":"), -180, 360); s32 saturation = sf.at_end() ? defaultSaturation : mystoi(sf.next(":"), -100, 1000); s32 lightness = sf.at_end() ? 0 : mystoi(sf.next(":"), -100, 100); @@ -2005,7 +2019,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, } /* [overlay:filename - or + or [hardlight:filename "A.png^[hardlight:B.png" is the same as "B.png^[overlay:A.Png" @@ -2069,7 +2083,7 @@ bool TextureSource::generateImagePart(std::string part_of_name, s32 contrast = mystoi(sf.next(":"), -127, 127); s32 brightness = sf.at_end() ? 0 : mystoi(sf.next(":"), -127, 127); - apply_brightness_contrast(baseimg, v2u32(0, 0), + apply_brightness_contrast(baseimg, v2u32(0, 0), baseimg->getDimension(), brightness, contrast); } else @@ -2347,14 +2361,14 @@ static void apply_overlay(video::IImage *blend, video::IImage *dst, v2s32 blend_layer_pos = hardlight ? dst_pos : blend_pos; v2s32 base_layer_pos = hardlight ? blend_pos : dst_pos; - for (u32 y = 0; y < size.Y; y++) + for (u32 y = 0; y < size.Y; y++) for (u32 x = 0; x < size.X; x++) { s32 base_x = x + base_layer_pos.X; s32 base_y = y + base_layer_pos.Y; video::SColor blend_c = blend_layer->getPixel(x + blend_layer_pos.X, y + blend_layer_pos.Y); - video::SColor base_c = base_layer->getPixel(base_x, base_y); + video::SColor base_c = base_layer->getPixel(base_x, base_y); double blend_r = blend_c.getRed() / 255.0; double blend_g = blend_c.getGreen() / 255.0; double blend_b = blend_c.getBlue() / 255.0; @@ -2373,7 +2387,7 @@ static void apply_overlay(video::IImage *blend, video::IImage *dst, } } -/* +/* Adjust the brightness and contrast of the base image. Conceptually like GIMP's "Brightness-Contrast" feature but allows brightness to be @@ -2387,17 +2401,17 @@ static void apply_brightness_contrast(video::IImage *dst, v2u32 dst_pos, v2u32 s // (we could technically allow -128/128 here as that would just result in 0 slope) double norm_c = core::clamp(contrast, -127, 127) / 128.0; double norm_b = core::clamp(brightness, -127, 127) / 127.0; - + // Scale brightness so its range is -127.5 to 127.5, otherwise brightness // adjustments will outputs values from 0.5 to 254.5 instead of 0 to 255. double scaled_b = brightness * 127.5 / 127; - // Calculate a contrast slope such that that no colors will get clamped due + // Calculate a contrast slope such that that no colors will get clamped due // to the brightness setting. // This allows the texture modifier to used as a brightness modifier without // the user having to calculate a contrast to avoid clipping at that brightness. double slope = 1 - fabs(norm_b); - + // Apply the user's contrast adjustment to the calculated slope, such that // -127 will make it near-vertical and +127 will make it horizontal double angle = atan(slope);