/trunk/CHANGELOG.md |
---|
7,6 → 7,7 |
- `val(i,a,b)` now returns the same value like Filter Factory for illegal values of `i`. |
- Windows: Standalone filters containing a `&` in Name or Category now have the correct "Visual Themes", as the Manifest XML is not broken anymore. |
- Introduced obfuscation version 7, which is more secure. |
- Windows: Handling of ampersand characters ("&") in Title, Category, Author, Copyright, and Controller/Map labels fixed. |
(*) This bug/solution was tested on Windows but needs to be verified and/or implemented on Mac. |
/trunk/ff.h |
---|
156,9 → 156,12 |
Boolean setup(FilterRecordPtr pb); |
void evalpixel(unsigned char *outp,unsigned char *inp); |
// from ui.c |
void strcpy_win_replace_ampersand(char* dst, char* src); |
// from make.c |
unsigned long printablehash(unsigned long hash); |
size_t fixpipl(PIPropertyList *pipl,size_t origsize,char* title, long *event_id); |
size_t fixpipl(PIPropertyList *pipl,size_t origsize,char* title, char* category, long *event_id); |
size_t aete_generate(void* aeteptr, PARM_T *pparm, long event_id); |
// from obfusc.c |
/trunk/make.c |
---|
153,7 → 153,7 |
return x + pad; |
} |
size_t fixpipl(PIPropertyList *pipl, size_t origsize, char* title, long *event_id) { |
size_t fixpipl(PIPropertyList *pipl, size_t origsize, char* title, char* category, long *event_id) { |
PIProperty *prop; |
char *p; |
struct hstm_data { |
211,9 → 211,9 |
prop->propertyKey = PICategoryProperty; |
prop->propertyID = 0; |
prop->propertyLength = (SPInt32)roundToNext4(strlen(gdata->parm.szCategory) + 1); |
prop->propertyLength = (SPInt32)roundToNext4(strlen(category) + 1); |
memset(prop->propertyData, 0x00, prop->propertyLength); // fill padding with 00h bytes (cosmetics) |
myc2pstrcpy((StringPtr)prop->propertyData, gdata->parm.szCategory); |
myc2pstrcpy((StringPtr)prop->propertyData, category); |
p += offsetof(PIProperty, propertyData) + prop->propertyLength; |
prop = (PIProperty*)p; |
222,9 → 222,7 |
hstm = (struct hstm_data*)prop->propertyData; |
sprintf(szScope, "%s %s", |
gdata->parm.szCategory, |
title); |
sprintf(szScope, "%s %s", category, title); |
#ifdef ENABLE_APPLESCRIPT |
// If the uniqueString/scope is set, the plugin will only communicate with Photoshop. |
/trunk/make_mac.c |
---|
41,7 → 41,7 |
Handle hpipl,h; |
long origsize,newsize,parm_type,parm_id; |
OSErr e = noErr; |
Str255 title; |
Str255 title, category; |
long event_id; |
#ifdef MACMACHO |
79,10 → 79,12 |
if(gdata->parm.popDialog) |
PLstrcat(title,"\pÉ"); |
myc2pstrcpy(category,gdata->parm.szCategory); |
origsize = GetHandleSize(hpipl); |
SetHandleSize(hpipl,origsize+0x300); /* some slop for fixup to work with */ |
HLock(hpipl); |
newsize = fixpipl((PIPropertyList*) *hpipl,origsize,title,&event_id); |
newsize = fixpipl((PIPropertyList*) *hpipl,origsize,title,category,&event_id); |
HUnlock(hpipl); |
SetHandleSize(hpipl,newsize); |
/trunk/make_win.c |
---|
392,12 → 392,12 |
char* manifestp_copy; |
PARM_T *pparm = NULL; |
size_t piplsize,aetesize,origsize; |
char title[256]; |
char title[256], category[256]; |
LPCTSTR parm_type; |
LPCTSTR parm_id; |
Boolean discard = true; |
uint64_t obfuscseed = 0, obfuscseed2 = 0; |
long event_id; |
long event_id = 0; |
memset(&dummy_oper, 0, sizeof(operdef_t)); |
memset(&dummy_func, 0, sizeof(funcdef_t)); |
419,10 → 419,12 |
newmanifest = (char*)malloc((size_t)manifestsize + 4096/*+4KiB for name,description,etc.*/); |
strcpy(title,gdata->parm.szTitle); |
strcpy_win_replace_ampersand(&title[0], &gdata->parm.szTitle[0]); |
if(gdata->parm.popDialog) |
strcat(title,"..."); |
strcpy_win_replace_ampersand(&category[0], &gdata->parm.szCategory[0]); |
origsize = SizeofResource(hDllInstance,datarsrc); |
if( (newpipl = (Ptr)malloc(origsize+0x300)) |
435,7 → 437,7 |
memcpy(newpipl,datap,origsize); |
/* note that Windows PiPLs have 2 byte version datum in front |
that isn't reflected in struct definition or Mac resource template: */ |
piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,&title[0], &event_id) + 2; |
piplsize = fixpipl((PIPropertyList*)(newpipl+2),origsize-2,&title[0],&category[0],&event_id) + 2; |
/* set up the PARM resource with saved parameters */ |
memcpy(pparm,&gdata->parm,sizeof(PARM_T)); |
/trunk/ui.c |
---|
254,6 → 254,27 |
/* one-time initialisation of dialog box */ |
void strcpy_win_replace_ampersand(char *dst, char *src) { |
size_t i; |
for (i = 0; i < strlen(src); i++) { |
#ifdef WIN_ENV |
// & needs to be replaced to && in: |
// - Labels (SETCTLTEXT) |
// - Menu items (i.e. PIPL) |
// It is not required in: |
// - Filedialog FileName |
// - MessageBox title or content |
// - Window titles |
// - Input boxes, e.g. import+export of an existing filter |
if (src[i] == '&') { |
*dst++ = src[i]; |
} |
#endif |
*dst++ = src[i]; |
} |
*dst++ = '\0'; |
} |
void maindlginit(DIALOGREF dp){ |
char s[0x100]; |
int i; |
265,8 → 286,10 |
/* hide unused expression items */ |
if(gdata->standalone){ |
SetDlgItemTextA(dp,PARAMAUTHORITEM,gdata->parm.szAuthor); |
SetDlgItemTextA(dp,PARAMCOPYITEM,gdata->parm.szCopyright); |
strcpy_win_replace_ampersand(&s[0], &gdata->parm.szAuthor[0]); |
SETCTLTEXT(dp,PARAMAUTHORITEM,s); |
strcpy_win_replace_ampersand(&s[0], &gdata->parm.szCopyright[0]); |
SETCTLTEXT(dp,PARAMCOPYITEM,s); |
// update labels for map() or ctl() sliders |
for(i = 0; i < 8; ++i){ |
273,14 → 296,14 |
if(gdata->parm.map_used[i/2]){ |
if((i&1) == 0){ |
// even (0, 2, 4, 6) |
strcpy(s,gdata->parm.szMap[i/2]); |
SetDlgItemTextA(dp, FIRSTMAPLABELITEM+(i/2),s); |
strcpy_win_replace_ampersand(&s[0], &gdata->parm.szMap[i/2][0]); |
SETCTLTEXT(dp, FIRSTMAPLABELITEM + (i/2),s); |
HideDialogItem(dp, FIRSTCTLLABELITEM + i); |
HideDialogItem(dp, FIRSTCTLLABELITEM + i + 1); |
} |
} else if(gdata->parm.ctl_used[i]){ |
strcpy(s,gdata->parm.szCtl[i]); |
SetDlgItemTextA(dp, FIRSTCTLLABELITEM+i,s); |
strcpy_win_replace_ampersand(&s[0], &gdata->parm.szCtl[i][0]); |
SETCTLTEXT(dp, FIRSTCTLLABELITEM+i,s); |
HideDialogItem(dp, FIRSTMAPLABELITEM + i/2); |
}else{ |
HideDialogItem(dp, FIRSTCTLITEM+i); |
299,7 → 322,7 |
HideDialogItem(dp,FIRSTLABELITEM+i); |
}else{ |
s[0] = channelsuffixes[gpb->imageMode][i]; |
SetDlgItemTextA(dp,FIRSTLABELITEM+i,s); |
SETCTLTEXT(dp,FIRSTLABELITEM+i,s); |
} |
} |
/trunk/ui_build.c |
---|
33,32 → 33,32 |
char s[0x100]; |
if(gdata->parmloaded){ |
SetDlgItemTextA(dp,CATEGORYITEM, gdata->parm.szCategory); |
SetDlgItemTextA(dp,TITLEITEM, gdata->parm.szTitle); |
SetDlgItemTextA(dp,COPYRIGHTITEM,gdata->parm.szCopyright); |
SetDlgItemTextA(dp,AUTHORITEM, gdata->parm.szAuthor); |
SETCTLTEXT(dp,CATEGORYITEM, gdata->parm.szCategory); |
SETCTLTEXT(dp,TITLEITEM, gdata->parm.szTitle); |
SETCTLTEXT(dp,COPYRIGHTITEM,gdata->parm.szCopyright); |
SETCTLTEXT(dp,AUTHORITEM, gdata->parm.szAuthor); |
for(i=0;i<4;++i){ |
SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,gdata->parm.szMap[i]); |
SETCTLTEXT(dp,FIRSTMAPNAMEITEM+i,gdata->parm.szMap[i]); |
} |
for(i=0;i<8;++i){ |
SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,gdata->parm.szCtl[i]); |
SETCTLTEXT(dp,FIRSTCTLNAMEITEM+i,gdata->parm.szCtl[i]); |
} |
}else{ |
/* strictly speaking this is not needed on the Mac, |
we can set initial values statically in the rez description */ |
SetDlgItemTextA(dp,CATEGORYITEM, "Filter Foundry"); |
SetDlgItemTextA(dp,TITLEITEM, "Untitled"); |
SetDlgItemTextA(dp,COPYRIGHTITEM,""); //"Filter Foundry Copyright (C) 2003-2009 Toby Thain, 2018-" RELEASE_YEAR " Daniel Marschall" |
SetDlgItemTextA(dp,AUTHORITEM, "Anonymous"); |
SETCTLTEXT(dp,CATEGORYITEM, "Filter Foundry"); |
SETCTLTEXT(dp,TITLEITEM, "Untitled"); |
SETCTLTEXT(dp,COPYRIGHTITEM,""); //"Filter Foundry Copyright (C) 2003-2009 Toby Thain, 2018-" RELEASE_YEAR " Daniel Marschall" |
SETCTLTEXT(dp,AUTHORITEM, "Anonymous"); |
strcpy(s,"Map X"); |
for(i = 0; i < 4; ++i){ |
s[4] = (char)('0' + i); |
SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,s); |
SETCTLTEXT(dp,FIRSTMAPNAMEITEM+i,s); |
} |
strcpy(s,"ctl(X)"); |
for(i = 0; i < 8; ++i){ |
s[4] = (char)('0' + i); |
SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,s); |
SETCTLTEXT(dp,FIRSTCTLNAMEITEM+i,s); |
} |
} |