Skip to content

set_at now take a long long for y instead of int #2962

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions src_c/draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1209,8 +1209,11 @@ clip_line(SDL_Surface *surf, int *x1, int *y1, int *x2, int *y2, int width,
}

static int
set_at(SDL_Surface *surf, int x, int y, Uint32 color)
set_at(SDL_Surface *surf, int x, long long y, Uint32 color)
{
// y should be long long so that y * surf->pitch doesn't overflow the int
// bounds in the case of very large surfaces and drawing on the edge of
// them
SDL_PixelFormat *format = surf->format;
Uint8 *pixels = (Uint8 *)surf->pixels;
Uint8 *byte_buf, rgb[4];
Expand Down Expand Up @@ -1250,7 +1253,7 @@ static void
set_and_check_rect(SDL_Surface *surf, int x, int y, Uint32 color,
int *drawn_area)
{
if (set_at(surf, x, y, color))
if (set_at(surf, x, (long long)y, color))
add_pixel_to_drawn_list(x, y, drawn_area);
}

Expand Down Expand Up @@ -1544,7 +1547,7 @@ drawhorzlineclip(SDL_Surface *surf, Uint32 color, int x1, int y1, int x2)
return;

if (x1 == x2) {
set_at(surf, x1, y1, color);
set_at(surf, x1, (long long)y1, color);
return;
}
drawhorzline(surf, color, x1, y1, x2);
Expand Down
14 changes: 13 additions & 1 deletion test/draw_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import math
import unittest
import sys
import os
import warnings

import pygame
Expand Down Expand Up @@ -1847,6 +1847,18 @@ def test_line_clipping_with_thickness(self):
"start={}, end={}".format(end_points[n], start_points[n]),
)

@unittest.skipIf("CI" in os.environ, "Surface is too large for CI to handle")
def test_line_draw_large_surf_regression(self):
"""Regression test for https://github.com/pygame-community/pygame-ce/issues/2961"""
try:
surface = pygame.Surface((14457, 37200))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the addition of this test. It makes the assumption that the host has enough memory.

A better solution would be a RAM check with pygame.system.get_total_ram, and then running this test if the RAM is above some threshold, but I'm not a fan of this either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't particularly like it either, but I felt it would be better to have some way to test that it hasn't regressed in the future. I couldn't think of any solution other than "make a gigantic surface" that CI won't have the memory for. I did try to make the surface as small as I could and still cause the segfault without the changes from this branch

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A follow-up of my message, yes I think it's not the method to follow to add the test.

except pygame.error:
self.skipTest("Surface too large to run this test in this environment")

point1 = [400, 37135]
point2 = [401, 37136]
pygame.draw.line(surface, (255, 255, 255), point1, point2, 1)


### Lines Testing #############################################################

Expand Down
Loading