Subversion Repositories filter_foundry

Compare Revisions

Regard whitespace Rev 541 → Rev 540

/trunk/CHANGELOG.md
1,9 → 1,5
# Changelog
 
## 1.7.0.21 [Work-In-Progress]
- Read FFX file: Fixed buffer overflow when some strings (Title,Category,Author,Copyright,SliderNames) are too long
- Read GUF file: Only the last part of the Category will be imported
 
## 1.7.0.20 [21-Nov-2023]
- Implemented "GIMP UserFilter" (GUF) file format.
 
/trunk/read.c
1,7 → 1,7
/*
This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.net
Copyright (C) 2018-2023 Daniel Marschall, ViaThinkSoft
Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
219,30 → 219,18
simplewarning_id(MSG_FILTERS_UNLIMITED_WARNING_ID);
 
val = _ffx_read_str(&q);
if (strlen(val) >= sizeof(gdata->parm.szTitle)) {
val[sizeof(gdata->parm.szTitle) - 1] = '\0';
}
strcpy(gdata->parm.szTitle, val);
free(val);
 
val = _ffx_read_str(&q);
if (strlen(val) >= sizeof(gdata->parm.szCategory)) {
val[sizeof(gdata->parm.szCategory) - 1] = '\0';
}
strcpy(gdata->parm.szCategory, val);
free(val);
 
val = _ffx_read_str(&q);
if (strlen(val) >= sizeof(gdata->parm.szAuthor)) {
val[sizeof(gdata->parm.szAuthor) - 1] = '\0';
}
strcpy(gdata->parm.szAuthor, val);
free(val);
 
val = _ffx_read_str(&q);
if (strlen(val) >= sizeof(gdata->parm.szCopyright)) {
val[sizeof(gdata->parm.szCopyright) - 1] = '\0';
}
strcpy(gdata->parm.szCopyright, val);
free(val);
 
255,7 → 243,7
// "Intro channel" existing
// C++ wrong warning: Using uninitialized memory "val2" (C6001)
#pragma warning(suppress : 6001)
char* combined = (char*)malloc(strlen(val) + strlen(",") + strlen(val2) + 1/*NUL byte*/);
char* combined = (char*)malloc(strlen(val) + strlen(",") + strlen(val2) + 1);
if (combined != NULL) {
sprintf(combined, "%s,%s", val, val2);
free(val);
302,9 → 290,6
if ((sliderName[0] == '{') && (sliderName[1] == 'S') && (sliderName[2] == '}')) sliderName += 3;
else if ((sliderName[0] == '{') && (sliderName[1] == 'C') && (sliderName[2] == '}')) sliderName += 3;
}
if (strlen(val) >= sizeof(gdata->parm.szCtl[i])) {
val[sizeof(gdata->parm.szCtl[i]) - 1] = '\0';
}
strcpy(gdata->parm.szCtl[i], sliderName);
free(val);
gdata->parm.ctl_used[i] = (bool32_t)*((byte*)q);
577,7 → 562,7
if (inputFile == NULL) return false;
// Let input memory be read-only, +1 for terminal zero
//char* inputwork = inputFile;
inputwork = (char*)malloc((size_t)maxInput + 1/*NUL byte*/);
inputwork = (char*)malloc((size_t)maxInput + 1);
inputworkinitial = inputwork;
if (inputwork == NULL) return false;
memcpy(inputwork, inputFile, maxInput);
599,11 → 584,11
if (x) memcpy(x, "Author:", strlen("Author:"));
// Controls:
for (i = 0; i < 8; i++) {
k1 = (char*)malloc(strlen("Control X:") + 1/*NUL byte*/);
k1 = (char*)malloc(strlen("Control X:") + 1);
sprintf(k1, "Control %d:", (int)i);
x = strstr(inputwork, k1);
if (x) {
k2 = (char*)malloc(strlen("ctl[X]: ") + 1/*NUL byte*/);
k2 = (char*)malloc(strlen("ctl[X]: ") + 1);
sprintf(k2, "ctl[%d]: ", (int)i);
memcpy(x, k2, strlen(k2));
x += strlen("ctl[X]");
614,11 → 599,11
}
// Maps:
for (i = 0; i < 4; i++) {
k1 = (char*)malloc(strlen("Map X:") + 1/*NUL byte*/);
k1 = (char*)malloc(strlen("Map X:") + 1);
sprintf(k1, "Map %d:", (int)i);
x = strstr(inputwork, k1);
if (x) {
k2 = (char*)malloc(strlen("map[X]:") + 1/*NUL byte*/);
k2 = (char*)malloc(strlen("map[X]:") + 1);
sprintf(k2, "map[%d]:", (int)i);
memcpy(x, k2, strlen(k2));
x += strlen("map[X]");
731,8 → 716,8
FILECOUNT count = (FILECOUNT)PIGETHANDLESIZE(h);
char* q = PILOCKHANDLE(h, false);
 
char dummy[256];
if (_picoReadProperty(q, count, "Title", dummy, sizeof(dummy), false)) {
char out[256];
if (_picoReadProperty(q, count, "Title", out, sizeof(out), false)) {
int i;
 
// Plugin infos
758,7 → 743,7
 
for (i = 0; i < 8; i++) {
int v;
char keyname[6/*strlen("ctl[X]")*/ + 1/*strlen("\0")*/], tmp[5];
char keyname[7+1], tmp[5];
 
// Slider names
sprintf(keyname, "ctl[%d]", i);
780,7 → 765,7
 
// Map names
for (i = 0; i < 4; i++) {
char keyname[6/*strlen("map[X]")*/ + 1/*strlen("\0")*/];
char keyname[7+1];
sprintf(keyname, "map[%d]", i);
_picoReadProperty(q, count, keyname, gdata->parm.szMap[i], sizeof(gdata->parm.szMap[i]), false);
}
812,7 → 797,7
 
// Handle argMaxInputLength
//char* inputwork = fileContents;
inputwork = (char*)malloc((size_t)argMaxInputLength + 1/*NUL byte*/);
inputwork = (char*)malloc((size_t)argMaxInputLength + 1);
if (inputwork == NULL) return false;
memcpy(inputwork, fileContents, argMaxInputLength);
inputwork[argMaxInputLength] = '\0';
819,7 → 804,7
 
// Prepare the input file contents to make it easier parse-able
iTmp = strlen(inputwork) + strlen("\n\n[");
tmpFileContents = (char*)malloc(iTmp + 1/*NUL byte*/);
tmpFileContents = (char*)malloc(iTmp + 1);
if (tmpFileContents == NULL) return false;
sprintf(tmpFileContents, "\n%s\n[", inputwork);
for (iTmp = 0; iTmp < strlen(tmpFileContents); iTmp++) {
828,7 → 813,7
 
// Find the section begin
iTmp = strlen(section) + strlen("\n[]\n");
tmpSection = (char*)malloc(iTmp + 1/*NUL byte*/);
tmpSection = (char*)malloc(iTmp + 1);
if (tmpSection == NULL) return false;
sprintf(tmpSection, "\n[%s]\n", section);
tmpStart = strstr(tmpFileContents, tmpSection);
887,8 → 872,6
Boolean res = false;
FILEREF refnum;
 
// TODO: Decode UTF-8 to ANSI (or "?" for unknown characters)
 
if (!fileHasExtension(sfr, TEXT(".guf"))) return false;
 
if (FSpOpenDF(&sfr->sfFile, fsRdPerm, &refnum) == noErr) {
915,18 → 898,10
}
if (_gufReadProperty(q, count, "Info", "Title", out, sizeof(out))) {
int i;
char tmp[256];
char* tmp2;
 
// Plugin infos
_gufReadProperty(q, count, "Info", "Title", gdata->parm.szTitle, sizeof(gdata->parm.szTitle));
_gufReadProperty(q, count, "Info", "Category", tmp, sizeof(tmp));
tmp2 = strrchr(tmp, '/');
if (tmp2 == NULL) {
strcpy(gdata->parm.szCategory, tmp);
} else {
strcpy(gdata->parm.szCategory, tmp2+1);
}
_gufReadProperty(q, count, "Info", "Category", gdata->parm.szCategory, sizeof(gdata->parm.szCategory)); // TODO: only last part of "/"
_gufReadProperty(q, count, "Info", "Author", gdata->parm.szAuthor, sizeof(gdata->parm.szAuthor));
_gufReadProperty(q, count, "Info", "Copyright", gdata->parm.szCopyright, sizeof(gdata->parm.szCopyright));
//_gufReadProperty(q, count, "Filter Factory", "8bf", gdata->parm.xxx, sizeof(gdata->parm.xxx));
947,7 → 922,7
 
for (i = 0; i < 8; i++) {
int v;
char keyname[9/*strlen("Control X")*/ + 1/*strlen("\0")*/], tmp[5];
char keyname[10 + 1], tmp[5];
sprintf(keyname, "Control %d", i);
 
// Slider names
965,7 → 940,7
 
// Map names
for (i = 0; i < 4; i++) {
char keyname[5/*strlen("Map X")*/ + 1/*strlen("\0")*/];
char keyname[6 + 1];
sprintf(keyname, "Map %d", i);
_gufReadProperty(q, count, keyname, "Label", gdata->parm.szMap[i], sizeof(gdata->parm.szMap[i]));
}
/trunk/save.c
1,7 → 1,7
/*
This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.net
Copyright (C) 2018-2023 Daniel Marschall, ViaThinkSoft
Copyright (C) 2018-2022 Daniel Marschall, ViaThinkSoft
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
223,7 → 223,7
if (!(e = PISETHANDLESIZE(h, (int32)(est))) && (p = start = PILOCKHANDLE(h, false))) {
char strBuildDate[11/*strlen("0000-00-00") + 1*/];
time_t iBuildDate = time(0);
strftime(strBuildDate, 11, "%Y-%m-%d", localtime(&iBuildDate));
strftime(strBuildDate, 100, "%Y-%m-%d", localtime(&iBuildDate));
 
checksliders(4, ctls, maps);