Warn if a unsupported bitmap format is used (Bug #681 & FR #559)

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7273 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2021-06-25 20:44:37 +00:00
parent 774a70ae93
commit ef6d0510ec
11 changed files with 61 additions and 9 deletions

View file

@ -214,12 +214,14 @@ Var mui.Button.Back
${if} $(^RTL) == 1
File "/oname=$PLUGINSDIR\modern-header.bmp" "${MUI_HEADERIMAGE_${UN}BITMAP_RTL}"
!pragma verifyloadimage "${MUI_HEADERIMAGE_${UN}BITMAP_RTL}"
!insertmacro MUI_HEADERIMAGE_INITHELPER_LOADIMAGE "${UN}" "_RTL" ${IMGRESID} "$PLUGINSDIR\modern-header.bmp"
${else}
!endif
File "/oname=$PLUGINSDIR\modern-header.bmp" "${MUI_HEADERIMAGE_${UN}BITMAP}"
!pragma verifyloadimage "${MUI_HEADERIMAGE_${UN}BITMAP}"
!insertmacro MUI_HEADERIMAGE_INITHELPER_LOADIMAGE "${UN}" "" ${IMGRESID} "$PLUGINSDIR\modern-header.bmp"
!ifdef MUI_HEADERIMAGE_${UN}BITMAP_RTL

View file

@ -91,6 +91,7 @@ Finish page (implemented using nsDialogs)
InitPluginsDir
File "/oname=$PLUGINSDIR\modern-wizard.bmp" "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}WELCOMEFINISHPAGE_BITMAP}"
!pragma verifyloadimage "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}WELCOMEFINISHPAGE_BITMAP}"
!ifdef MUI_${MUI_PAGE_UNINSTALLER_PREFIX}PAGE_FUNCTION_GUIINIT
Call "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}PAGE_FUNCTION_GUIINIT}"

View file

@ -43,6 +43,7 @@ Welcome page (implemented using nsDialogs)
InitPluginsDir
File "/oname=$PLUGINSDIR\modern-wizard.bmp" "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}WELCOMEFINISHPAGE_BITMAP}"
!pragma verifyloadimage "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}WELCOMEFINISHPAGE_BITMAP}"
!ifdef MUI_${MUI_PAGE_UNINSTALLER_PREFIX}PAGE_FUNCTION_GUIINIT
Call "${MUI_${MUI_PAGE_UNINSTALLER_PREFIX}PAGE_FUNCTION_GUIINIT}"

View file

@ -452,6 +452,7 @@ Var MUI_TEMP2
!insertmacro INSTALLOPTIONS_EXTRACT_AS "${MUI_${UNINSTALLER}WELCOMEFINISHPAGE_INI}" "ioSpecial.ini"
File "/oname=$PLUGINSDIR\modern-wizard.bmp" "${MUI_${UNINSTALLER}WELCOMEFINISHPAGE_BITMAP}"
!pragma verifyloadimage "${MUI_${UNINSTALLER}WELCOMEFINISHPAGE_BITMAP}"
!insertmacro INSTALLOPTIONS_WRITE "ioSpecial.ini" "Field 1" "Text" "$PLUGINSDIR\modern-wizard.bmp"
@ -474,6 +475,7 @@ Var MUI_TEMP2
StrCmp $(^RTL) 0 mui.headerimageinit_nortl
File "/oname=$PLUGINSDIR\modern-header.bmp" "${MUI_HEADERIMAGE_${UNINSTALLER}BITMAP_RTL}"
!pragma verifyloadimage "${MUI_HEADERIMAGE_${UNINSTALLER}BITMAP_RTL}"
!ifndef MUI_HEADERIMAGE_${UNINSTALLER}BITMAP_RTL_NOSTRETCH
SetBrandingImage /IMGID=1046 /RESIZETOFIT "$PLUGINSDIR\modern-header.bmp"
@ -488,6 +490,7 @@ Var MUI_TEMP2
!endif
File "/oname=$PLUGINSDIR\modern-header.bmp" "${MUI_HEADERIMAGE_${UNINSTALLER}BITMAP}"
!pragma verifyloadimage "${MUI_HEADERIMAGE_${UNINSTALLER}BITMAP}"
!ifndef MUI_HEADERIMAGE_${UNINSTALLER}BITMAP_NOSTRETCH
SetBrandingImage /IMGID=1046 /RESIZETOFIT "$PLUGINSDIR\modern-header.bmp"

View file

@ -485,3 +485,29 @@ DWORD IsBMPFile(const void*pData, size_t DataSize, GENERICIMAGEINFO*pInfo)
}
return 0;
}
bool LoadImageCanLoadFile(const void*pData, size_t DataSize)
{
bool valid = IsICOCURFile(pData, DataSize) != 0;
if (!valid)
{
GENERICIMAGEINFO info;
UINT headersize = GetBMPFileHeaderSize(pData, DataSize, &info);
valid = headersize == 12 || headersize == 40; // Only supports BITMAPCOREHEADER and BITMAPINFOHEADER (Bug #681 & FR #559)
valid = valid && !info.IsTopDownBitmap(); // TopDown bitmaps are only valid if they are loaded with LR_CREATEDIBSECTION, and if loaded from a resource, and if running on Vista+? and therefore we deny!
}
return valid;
}
bool LoadImageCanLoadFile(const TCHAR *filepath)
{
bool valid = false;
unsigned char header[14+124];
FILE *f = my_fopen(filepath, "rb");
if (f)
{
valid = LoadImageCanLoadFile(header, fread(header, 1, sizeof(header), f));
fclose(f);
}
return valid;
}

View file

@ -37,6 +37,7 @@ typedef struct GENERICIMAGEINFO {
DWORD GetDIBHeaderInfo(const void*pData, size_t DataSize, GENERICIMAGEINFO&Info);
DWORD IsBMPFile(const void*pData, size_t DataSize, GENERICIMAGEINFO*pInfo = 0);
#define GetBMPFileHeaderSize IsBMPFile
inline WORD IsICOCURFile(const void*pData)
{
@ -51,4 +52,8 @@ inline WORD IsICOCURFile(const void*pData, size_t DataSize)
return DataSize > 6 ? IsICOCURFile(pData) : 0;
}
bool LoadImageCanLoadFile(const void*pData, size_t DataSize);
bool LoadImageCanLoadFile(const TCHAR *filepath);
#define LoadImageCanLoadFileFromResource LoadImageCanLoadFile
#endif //~ NSIS_BININTEROP_H

View file

@ -31,6 +31,7 @@
#include "manifest.h"
#include "icon.h"
#include "utf.h" // For NStream
#include "BinInterop.h"
#include "exehead/api.h"
#include "exehead/resource.h"
@ -3403,12 +3404,18 @@ int CEXEBuild::parse_pragma(LineParser &line)
return rvErr;
}
if (line.gettoken_enum(1, _T("verifyloadimage\0")) == 0)
{
bool valid = LoadImageCanLoadFile(line.gettoken_str(2));
return valid ? rvSucc : (warning_fl(DW_BADFORMAT_EXTERNAL_FILE, _T("Unsupported format %") NPRIs, line.gettoken_str(2)), rvWarn);
}
// 2.47 shipped with a corrupted CHM file (bug #1129). This minimal verification command exists because the !searchparse hack we added does not work with codepage 936!
if (line.gettoken_enum(1, _T("verifychm\0")) == 0)
{
struct { UINT32 Sig, Ver, cbH; } chm;
NIStream f;
bool valid = f.OpenFileForReading(line.gettoken_str(2));
bool valid = f.OpenFileForReading(line.gettoken_str(2), NStreamEncoding::BINARY);
valid = valid && 12 == f.ReadOctets(&chm, 12);
valid = valid && FIX_ENDIAN_INT32(chm.Sig) == 0x46535449 && (FIX_ENDIAN_INT32(chm.Ver)|1) == 3; // 'ITSF' v2..3
return valid ? rvSucc : (ERROR_MSG(_T("Error: Invalid format\n")), PS_ERROR);

View file

@ -71,6 +71,7 @@ typedef enum {
//DE_PP_VERBOSE_BAD_LEVEL = 4000?,
//DW_STALE_TEMP = 5020?, TODO: There is currently no way to disable this
DW_PACKHDR_RETNONZERO = 5021,
DW_BADFORMAT_EXTERNAL_FILE = 5040,
DW_UNSUPP_STORE_FILE_ATT = 5050,
//DW_CMDLINE_UNSUPP = 5200?,
//DW_CMDLINE_UNSUPP_WIN = 5201?,

View file

@ -363,6 +363,7 @@ void NStreamEncoding::GetCPDisplayName(WORD CP, TCHAR*Buf)
case UTF32LE: p = _T("UTF32LE"); break;
case UTF32BE: p = _T("UTF32BE"); break;
case UTF8: p = _T("UTF8"); break;
case BINARY: p = _T("BIN"); break;
default:
_stprintf(mybuf,_T("CP%u"),CP);
if (CP >= NStreamEncoding::CPCOUNT) p = _T("?");
@ -376,13 +377,17 @@ bool NBaseStream::Attach(FILE*hFile, WORD enc, bool Seek /*= true*/)
m_hFile = hFile;
if (!m_hFile) return false;
if (!NStream::SetBinaryMode(m_hFile) && m_hFile != stdin) return false;
fpos_t pos;
if (Seek && !fgetpos(m_hFile, &pos)) rewind(m_hFile); else Seek = false;
WORD cp = DetectUTFBOM(m_hFile);
if (Seek)
WORD cp = 0;
if (enc != NStreamEncoding::BINARY)
{
fsetpos(m_hFile, &pos);
if (cp) DetectUTFBOM(m_hFile); // parseScript() etc does not like the BOM, make sure we skip past it
fpos_t pos;
if (Seek && !fgetpos(m_hFile, &pos)) rewind(m_hFile); else Seek = false;
cp = DetectUTFBOM(m_hFile);
if (Seek)
{
fsetpos(m_hFile, &pos);
if (cp) DetectUTFBOM(m_hFile); // parseScript() etc does not like the BOM, make sure we skip past it
}
}
if (!cp) cp = enc;
m_Enc.SafeSetCodepage(cp);

View file

@ -185,7 +185,8 @@ public:
UTF8 = CP_UTF8,
UNKNOWN = (0xffff-0),
AUTO = (0xffff-1),
CPCOUNT = (0xffff-2) // Must be less than our other magic numbers
BINARY = (0xffff-2),
CPCOUNT = (0xffff-3) // Must be less than our other magic numbers
};
NStreamEncoding() { Reset(); }

View file

@ -146,7 +146,7 @@ int update_bitmap(CResourceEditor* re, WORD id, const TCHAR* filename, int width
signed char hdr[14+124], retval = -2;
size_t size = fread(hdr, 1, sizeof(hdr), f);
GENERICIMAGEINFO info;
if (IsBMPFile(hdr, size, &info) && 0 == fseek(f, 0, SEEK_SET) && !info.IsTopDownBitmap())
if (IsBMPFile(hdr, size, &info) && 0 == fseek(f, 0, SEEK_SET) && LoadImageCanLoadFileFromResource(hdr, size))
{
if ((width && width != (int) info.Width) || (height && height != (int) info.Height))
retval = -3;