Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
SRB2
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
STJr
SRB2
Commits
161dab91
Commit
161dab91
authored
6 months ago
by
Lactozilla
Browse files
Options
Downloads
Patches
Plain Diff
Check if a lump is a valid patch when looking for one by name
parent
6ba33a39
No related branches found
No related tags found
1 merge request
!2621
Check if a lump is a valid patch when looking for one by name
Pipeline
#6881
passed
6 months ago
Stage: build
Changes
4
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/r_defs.h
+4
-0
4 additions, 0 deletions
src/r_defs.h
src/r_picformats.c
+12
-5
12 additions, 5 deletions
src/r_picformats.c
src/r_picformats.h
+10
-3
10 additions, 3 deletions
src/r_picformats.h
src/w_wad.c
+56
-40
56 additions, 40 deletions
src/w_wad.c
with
82 additions
and
48 deletions
src/r_defs.h
+
4
−
0
View file @
161dab91
...
...
@@ -910,6 +910,10 @@ typedef struct
#pragma pack()
#endif
#define MAX_PATCH_DIMENSIONS 8192
#define VALID_PATCH_LUMP_SIZE(lumplen, width) ((lumplen) >= (sizeof(INT16) * 4) + ((width) * sizeof(INT32)))
// Possible alpha types for a patch.
enum
patchalphastyle
{
AST_COPY
,
AST_TRANSLUCENT
,
AST_ADD
,
AST_SUBTRACT
,
AST_REVERSESUBTRACT
,
AST_MODULATE
,
AST_OVERLAY
,
AST_FOG
};
...
...
This diff is collapsed.
Click to expand it.
src/r_picformats.c
+
12
−
5
View file @
161dab91
...
...
@@ -811,13 +811,19 @@ boolean Picture_IsFlatFormat(pictureformat_t format)
*/
boolean
Picture_CheckIfDoomPatch
(
softwarepatch_t
*
patch
,
size_t
size
)
{
//
Minimum length of a valid Doom patch
if
(
size
<
13
)
//
Does not meet minimum size requirements
if
(
size
<
PATCH_MIN_SIZE
)
return
false
;
INT16
width
=
SHORT
(
patch
->
width
);
INT16
height
=
SHORT
(
patch
->
height
);
if
(
width
<=
0
||
height
<=
0
)
// Quickly check for the dimensions first.
if
(
width
<=
0
||
height
<=
0
||
width
>
MAX_PATCH_DIMENSIONS
||
height
>
MAX_PATCH_DIMENSIONS
)
return
false
;
// Lump size makes no sense given the width
if
(
!
VALID_PATCH_LUMP_SIZE
(
size
,
width
))
return
false
;
// The dimensions seem like they might be valid for a patch, so
...
...
@@ -829,7 +835,7 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
UINT32
ofs
=
LONG
(
patch
->
columnofs
[
x
]);
// Need one byte for an empty column (but there's patches that don't know that!)
if
(
ofs
<
(
UINT32
)
width
*
4
+
8
||
ofs
>=
(
UINT32
)
size
)
if
(
ofs
<
(
(
sizeof
(
INT16
)
*
4
)
+
(
width
*
sizeof
(
INT32
)))
||
ofs
>=
(
UINT32
)
size
)
{
return
false
;
}
...
...
@@ -897,8 +903,9 @@ void *Picture_TextureToFlat(size_t texnum)
*/
boolean
Picture_IsLumpPNG
(
const
UINT8
*
d
,
size_t
s
)
{
if
(
s
<
67
)
// https://web.archive.org/web/20230524232139/http://garethrees.org/2007/11/14/pngcrush/
if
(
s
<
PNG_MIN_SIZE
)
return
false
;
// Check for PNG file signature using memcmp
// As it may be faster on CPUs with slow unaligned memory access
// Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature
...
...
This diff is collapsed.
Click to expand it.
src/r_picformats.h
+
10
−
3
View file @
161dab91
...
...
@@ -55,6 +55,16 @@ enum
PICDEPTH_32BPP
=
32
};
// Minimum length of a valid Doom patch
#define PATCH_MIN_SIZE 13
// Minimum size of a PNG file.
// See: https://web.archive.org/web/20230524232139/http://garethrees.org/2007/11/14/pngcrush/
#define PNG_MIN_SIZE 67
// Size of a PNG header
#define PNG_HEADER_SIZE 8
void
*
Picture_Convert
(
pictureformat_t
informat
,
void
*
picture
,
pictureformat_t
outformat
,
size_t
insize
,
size_t
*
outsize
,
...
...
@@ -104,9 +114,6 @@ typedef struct
boolean
available
;
}
spriteinfo_t
;
// PNG support
#define PNG_HEADER_SIZE 8
boolean
Picture_IsLumpPNG
(
const
UINT8
*
d
,
size_t
s
);
#ifndef NO_PNG_LUMPS
...
...
This diff is collapsed.
Click to expand it.
src/w_wad.c
+
56
−
40
View file @
161dab91
...
...
@@ -1695,12 +1695,64 @@ lumpnum_t W_GetNumForLongName(const char *name)
return
i
;
}
// Checks if a given lump might be a valid patch.
// This will need to read a bit of the file, but it attempts to not load it
// in its entirety.
static
boolean
W_IsProbablyValidPatch
(
UINT16
wadnum
,
UINT16
lumpnum
)
{
UINT8
header
[
sizeof
(
INT16
)
*
4
];
I_StaticAssert
(
sizeof
(
header
)
>=
PNG_HEADER_SIZE
);
// Check the file's size first
size_t
lumplen
=
W_LumpLengthPwad
(
wadnum
,
lumpnum
);
// Cannot be a valid Doom patch
if
(
lumplen
<
PATCH_MIN_SIZE
)
return
false
;
// Check if it's probably a valid PNG
if
(
lumplen
>=
PNG_MIN_SIZE
)
{
// Read the PNG's header
W_ReadLumpHeaderPwad
(
wadnum
,
lumpnum
,
header
,
PNG_HEADER_SIZE
,
0
);
if
(
Picture_IsLumpPNG
(
header
,
lumplen
))
{
// Assume it is if the signature matches.
return
true
;
}
// Otherwise, we read it as a patch
}
// Read the first 8 bytes
W_ReadLumpHeaderPwad
(
wadnum
,
lumpnum
,
header
,
sizeof
(
header
),
0
);
INT16
width
=
((
UINT16
*
)
header
)[
0
];
INT16
height
=
((
UINT16
*
)
header
)[
1
];
// Lump size makes no sense given the width
if
(
!
VALID_PATCH_LUMP_SIZE
(
lumplen
,
width
))
return
false
;
// Check the dimensions.
if
(
width
>
0
&&
height
>
0
&&
width
<=
MAX_PATCH_DIMENSIONS
&&
height
<=
MAX_PATCH_DIMENSIONS
)
{
// Dimensions seem to make sense. Patch might be valid
return
true
;
}
// Not valid if this point was reached
return
false
;
}
//
// Same as W_CheckNumForNamePwad, but handles namespaces.
//
static
UINT16
W_CheckNumForPatchNamePwad
(
const
char
*
name
,
UINT16
wad
,
boolean
longname
)
{
UINT16
i
,
start
=
INT16_MAX
,
end
=
INT16_MAX
;
UINT16
i
;
static
char
uname
[
8
+
1
]
=
{
0
};
UINT32
hash
=
0
;
lumpinfo_t
*
lump_p
;
...
...
@@ -1715,51 +1767,15 @@ static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean l
hash
=
quickncasehash
(
uname
,
8
);
}
// SRB2 doesn't have a specific namespace for graphics, which means someone can do weird things
// like placing graphics inside a namespace it doesn't make sense for them to be in, like Sounds/ or SOC/
// So for now, this checks for lumps OUTSIDE of the flats namespace.
// When this situation changes, change the loops below to check for lumps INSIDE the namespaces to look in.
// TODO: cache namespace lump IDs
if
(
W_FileHasFolders
(
wadfiles
[
wad
]))
{
start
=
W_CheckNumForFolderStartPK3
(
"Flats/"
,
wad
,
0
);
end
=
W_CheckNumForFolderEndPK3
(
"Flats/"
,
wad
,
start
);
// if the start and end is the same, the folder is empty
if
(
end
<=
start
)
{
start
=
INT16_MAX
;
end
=
INT16_MAX
;
}
}
else
{
start
=
W_CheckNumForMarkerStartPwad
(
"F_START"
,
wad
,
0
);
end
=
W_CheckNumForNamePwad
(
"F_END"
,
wad
,
start
);
if
(
end
!=
INT16_MAX
)
end
++
;
}
lump_p
=
wadfiles
[
wad
]
->
lumpinfo
;
if
(
start
==
INT16_MAX
)
start
=
wadfiles
[
wad
]
->
numlumps
;
for
(
i
=
0
;
i
<
start
;
i
++
,
lump_p
++
)
for
(
i
=
0
;
i
<
wadfiles
[
wad
]
->
numlumps
;
i
++
,
lump_p
++
)
{
if
((
!
longname
&&
lump_p
->
hash
==
hash
&&
!
strncmp
(
lump_p
->
name
,
uname
,
sizeof
(
uname
)
-
1
))
||
(
longname
&&
stricmp
(
lump_p
->
longname
,
name
)
==
0
))
return
i
;
}
if
(
end
!=
INT16_MAX
&&
start
<
end
)
{
lump_p
=
wadfiles
[
wad
]
->
lumpinfo
+
end
;
for
(
i
=
end
;
i
<
wadfiles
[
wad
]
->
numlumps
;
i
++
,
lump_p
++
)
{
if
((
!
longname
&&
lump_p
->
hash
==
hash
&&
!
strncmp
(
lump_p
->
name
,
uname
,
sizeof
(
uname
)
-
1
))
||
(
longname
&&
stricmp
(
lump_p
->
longname
,
name
)
==
0
))
// Found the patch by name, but needs to check if it is valid.
if
(
W_IsProbablyValidPatch
(
wad
,
i
))
return
i
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment