Commit be37ea23 authored by Matt Mascarenhas's avatar Matt Mascarenhas

cinera: Replace all inline CSS and JS

We no longer prevent enforcement of strict server security policies (to
be documented)

Add bounds-checking to the Copy string functions, fixing buffer sizes

Fix the marker skipping (e.g. :afk)
parent 4a0630be
......@@ -2,6 +2,8 @@
ctime -begin ${0%.*}.ctm
#gcc -g -fsanitize=address -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl
gcc -O2 -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl
#clang -fsanitize=address -g -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl
#clang -O2 -Wall -std=c99 -pipe $0 -o ${0%.*} hmml.a -lcurl
ctime -end ${0%.*}.ctm
exit
#endif
......@@ -14,7 +16,7 @@ typedef struct
version CINERA_APP_VERSION = {
.Major = 0,
.Minor = 5,
.Patch = 45
.Patch = 46
};
// TODO(matt): Copy in the DB 3 stuff from cinera_working.c
......@@ -529,16 +531,13 @@ project_info ProjectInfo[] =
#define ArrayCount(A) sizeof(A)/sizeof(*(A))
__attribute__ ((format (printf, 2, 3)))
int
CopyString(char Dest[], char *Format, ...)
void
Clear(char *String, int Size)
{
int Length = 0;
va_list Args;
va_start(Args, Format);
Length = vsprintf(Dest, Format, Args);
va_end(Args);
return Length;
for(int i = 0; i < Size; ++i)
{
String[i] = 0;
}
}
int
......@@ -552,166 +551,223 @@ StringLength(char *String)
return i;
}
void
CopyBuffer(buffer *Dest, buffer *Src)
#define CopyString(Dest, DestSize, Format, ...) CopyString_(__LINE__, (Dest), (DestSize), (Format), ##__VA_ARGS__)
__attribute__ ((format (printf, 4, 5)))
int
CopyString_(int LineNumber, char Dest[], int DestSize, char *Format, ...)
{
Src->Ptr = Src->Location;
while(*Src->Ptr)
{
// TODO(matt)
{
if(Dest->Ptr - Dest->Location >= Dest->Size)
int Length = 0;
va_list Args;
va_start(Args, Format);
Length = vsnprintf(Dest, DestSize, Format, Args);
if(Length >= DestSize)
{
fprintf(stderr, "CopyBuffer: %s cannot accommodate %s\n", Dest->ID, Src->ID);
printf("CopyString() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string\n", LineNumber, DestSize, Length);
__asm__("int3");
}
}
*Dest->Ptr++ = *Src->Ptr++;
}
*Dest->Ptr = '\0';
}
void
Clear(char *String, int Size)
{
for(int i = 0; i < Size; ++i)
{
String[i] = 0;
}
va_end(Args);
return Length;
}
#define CopyStringNoFormat(Dest, DestSize, String) CopyStringNoFormat_(__LINE__, Dest, DestSize, String)
int
CopyStringNoFormat(char *Dest, char *String)
CopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, char *String)
{
int Length = 0;
char *Start = String;
while(*String)
{
*Dest++ = *String++;
++Length;
}
if(Length >= DestSize)
{
printf("CopyStringNoFormat() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string:\n"
"%s\n", LineNumber, DestSize, Length, Start);
__asm__("int3");
}
*Dest = '\0';
return Length;
}
#define ClearCopyStringNoFormat(Dest, DestSize, String) ClearCopyStringNoFormat_(__LINE__, Dest, DestSize, String)
int
ClearCopyStringNoFormat(char *Dest, int DestSize, char *String)
ClearCopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, char *String)
{
Clear(Dest, DestSize);
return(CopyStringNoFormat(Dest, String));
int Length = 0;
char *Start = String;
while(*String)
{
*Dest++ = *String++;
++Length;
}
if(Length >= DestSize)
{
printf("ClearCopyStringNoFormat() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %d(+1)-character string:\n"
"%s\n", LineNumber, DestSize, Length, Start);
__asm__("int3");
}
*Dest = '\0';
return Length;
}
// TODO(matt): Maybe do a version of this that takes a string as a Terminator
#define CopyStringNoFormatT(Dest, DestSize, String, Terminator) CopyStringNoFormatT_(__LINE__, Dest, DestSize, String, Terminator)
int
CopyStringNoFormatT(char *Dest, char *String, char Terminator)
CopyStringNoFormatT_(int LineNumber, char *Dest, int DestSize, char *String, char Terminator)
{
int Length = 0;
char *Start = String;
while(*String != Terminator)
{
*Dest++ = *String++;
++Length;
}
if(Length >= DestSize)
{
printf("CopyStringNoFormatT() call on line %d has been passed a buffer too small (%d bytes) to contain %c-terminated %d(+1)-character string:\n"
"%.*s\n", LineNumber, DestSize, Terminator == 0 ? '0' : Terminator, Length, Length, Start);
__asm__("int3");
}
*Dest = '\0';
return Length;
}
__attribute__ ((format (printf, 2, 3)))
#define CopyStringToBuffer(Dest, Format, ...) CopyStringToBuffer_(__LINE__, Dest, Format, ##__VA_ARGS__)
__attribute__ ((format (printf, 3, 4)))
void
CopyStringToBuffer(buffer *Dest, char *Format, ...)
CopyStringToBuffer_(int LineNumber, buffer *Dest, char *Format, ...)
{
va_list Args;
va_start(Args, Format);
int Length = vsnprintf(Dest->Ptr, Dest->Size - (Dest->Ptr - Dest->Location), Format, Args);
va_end(Args);
// TODO(matt)
{
if(Length + (Dest->Ptr - Dest->Location) >= Dest->Size)
{
fprintf(stderr, "CopyStringToBuffer: %s cannot accommodate %d-character string:\n"
"\n"
"%s\n", Dest->ID, Length, Format);
fprintf(stderr, "CopyStringToBuffer(%s) call on line %d cannot accommodate null-terminated %d(+1)-character string:\n"
"%s\n", Dest->ID, LineNumber, Length, Format);
__asm__("int3");
}
}
Dest->Ptr += Length;
}
#define CopyStringToBufferNoFormat(Dest, String) CopyStringToBufferNoFormat_(__LINE__, Dest, String)
void
CopyStringToBufferNoFormat(buffer *Dest, char *String)
CopyStringToBufferNoFormat_(int LineNumber, buffer *Dest, char *String)
{
char *Start = String;
while(*String)
{
*Dest->Ptr++ = *String++;
}
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %d-character string:\n"
"%s\n", Dest->ID, LineNumber, StringLength(Start), Start);
__asm__("int3");
}
*Dest->Ptr = '\0';
}
#define CopyStringToBufferHTMLSafe(Dest, String) CopyStringToBufferHTMLSafe_(__LINE__, Dest, String)
void
CopyStringToBufferHTMLSafe(buffer *Dest, char *String)
CopyStringToBufferHTMLSafe_(int LineNumber, buffer *Dest, char *String)
{
char *Start = String;
int Length = StringLength(String);
while(*String)
{
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferHTMLSafe: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
__asm__("int3");
}
switch(*String)
{
case '<': CopyStringToBuffer(Dest, "&lt;"); break;
case '>': CopyStringToBuffer(Dest, "&gt;"); break;
case '&': CopyStringToBuffer(Dest, "&amp;"); break;
case '\"': CopyStringToBuffer(Dest, "&quot;"); break;
case '\'': CopyStringToBuffer(Dest, "&#39;"); break;
case '<': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'l'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 3; break;
case '>': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'g'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 3; break;
case '&': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'a'; *Dest->Ptr++ = 'm'; *Dest->Ptr++ = 'p'; *Dest->Ptr++ = ';'; Length += 4; break;
case '\"': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'q'; *Dest->Ptr++ = 'u'; *Dest->Ptr++ = 'o'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 5; break;
case '\'': *Dest->Ptr++ = '&'; *Dest->Ptr++ = '#'; *Dest->Ptr++ = '3'; *Dest->Ptr++ = '9'; *Dest->Ptr++ = ';'; Length += 4; break;
default: *Dest->Ptr++ = *String; break;
}
++String;
}
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferHTMLSafe(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n"
"%s\n", Dest->ID, LineNumber, Length, Start);
__asm__("int3");
}
*Dest->Ptr = '\0';
}
#define CopyStringToBufferHTMLSafeBreakingOnSlash(Dest, String) CopyStringToBufferHTMLSafeBreakingOnSlash_(__LINE__, Dest, String)
void
CopyStringToBufferHTMLSafeBreakingOnSlash(buffer *Dest, char *String)
CopyStringToBufferHTMLSafeBreakingOnSlash_(int LineNumber, buffer *Dest, char *String)
{
char *Start = String;
int Length = StringLength(String);
while(*String)
{
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferHTMLSafeBreakingOnSlash: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
__asm__("int3");
}
switch(*String)
{
case '<': CopyStringToBuffer(Dest, "&lt;"); break;
case '>': CopyStringToBuffer(Dest, "&gt;"); break;
case '&': CopyStringToBuffer(Dest, "&amp;"); break;
case '\"': CopyStringToBuffer(Dest, "&quot;"); break;
case '\'': CopyStringToBuffer(Dest, "&#39;"); break;
case '/': CopyStringToBuffer(Dest, "/\u200B"); break;
case '<': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'l'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 3; break;
case '>': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'g'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 3; break;
case '&': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'a'; *Dest->Ptr++ = 'm'; *Dest->Ptr++ = 'p'; *Dest->Ptr++ = ';'; Length += 4; break;
case '\'': *Dest->Ptr++ = '&'; *Dest->Ptr++ = '#'; *Dest->Ptr++ = '3'; *Dest->Ptr++ = '9'; *Dest->Ptr++ = ';'; Length += 4; break;
case '\"': *Dest->Ptr++ = '&'; *Dest->Ptr++ = 'q'; *Dest->Ptr++ = 'u'; *Dest->Ptr++ = 'o'; *Dest->Ptr++ = 't'; *Dest->Ptr++ = ';'; Length += 5; break;
case '/': *Dest->Ptr++ = '/'; *Dest->Ptr++ = '&'; *Dest->Ptr++ = '#'; *Dest->Ptr++ = '8'; *Dest->Ptr++ = '2'; *Dest->Ptr++ = '0'; *Dest->Ptr++ = '3'; *Dest->Ptr++ = ';'; Length += 7; break;
default: *Dest->Ptr++ = *String; break;
}
++String;
}
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferHTMLSafeBreakingOnSlash_(%s) call on line %d cannot accommodate %d(+1)-character HTML-sanitised string:\n"
"%s\n", Dest->ID, LineNumber, Length, Start);
__asm__("int3");
}
}
#define CopyStringToBufferJSONSafe(Dest, String) CopyStringToBufferJSONSafe_(__LINE__, Dest, String)
void
CopyStringToBufferJSONSafe(buffer *Dest, char *String)
CopyStringToBufferJSONSafe_(int LineNumber, buffer *Dest, char *String)
{
char *Start = String;
int Length = StringLength(String);
while(*String)
{
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferJSONSafe: %s cannot accommodate %d-character string\n", Dest->ID, StringLength(String));
__asm__("int3");
}
switch(*String)
{
case '\\':
case '\"':
*Dest->Ptr++ = '\\';
++Length;
default:
*Dest->Ptr++ = *String++;
break;
}
}
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyStringToBufferJSONSafe(%s) call on line %d cannot accommodate %d(+1)-character JSON-sanitised string:\n"
"%s\n", Dest->ID, LineNumber, Length, Start);
__asm__("int3");
}
}
#define CopyBuffer(Dest, Src) CopyBuffer_(__LINE__, Dest, Src)
void
CopyBuffer_(int LineNumber, buffer *Dest, buffer *Src)
{
Src->Ptr = Src->Location;
while(*Src->Ptr)
{
*Dest->Ptr++ = *Src->Ptr++;
}
if(Dest->Ptr - Dest->Location >= Dest->Size)
{
fprintf(stderr, "CopyBuffer(%s) call on line %d cannot accommodate %d(+1)-character %s\n", Dest->ID, LineNumber, StringLength(Src->Location), Src->ID);
__asm__("int3");
}
*Dest->Ptr = '\0';
}
int
......@@ -827,7 +883,7 @@ LogError(int LogLevel, char *Format, ...)
if(Config.LogLevel >= LogLevel)
{
char LogPath[256];
CopyString(LogPath, "%s/%s", Config.CacheDir, "errors.log");
CopyString(LogPath, sizeof(LogPath), "%s/%s", Config.CacheDir, "errors.log");
FILE *LogFile;
if(!(LogFile = fopen(LogPath, "a+")))
{
......@@ -853,7 +909,7 @@ void
FreeBuffer(buffer *Buffer)
{
free(Buffer->Location);
Buffer->Location = '\0';
Buffer->Location = 0;
#if DEBUG_MEM
FILE *MemLog = fopen("/home/matt/cinera_mem", "a+");
fprintf(MemLog, " Freed %s\n", Buffer->ID);
......@@ -993,24 +1049,25 @@ ConstructTemplatePath(template *Template, int TemplateType)
if(Template->Metadata.Filename[0] != '/')
{
char Temp[256];
CopyString(Temp, Template->Metadata.Filename);
CopyString(Temp, sizeof(Temp), "%s", Template->Metadata.Filename);
char *Ptr = Template->Metadata.Filename;
char *End = Template->Metadata.Filename + sizeof(Template->Metadata.Filename);
if(TemplateType == TEMPLATE_BESPOKE)
{
if(Config.Edition == EDITION_SINGLE)
{
Ptr += CopyString(Ptr, "%s/", GetDirectoryPath(Config.SingleHMMLFilePath));
Ptr += CopyString(Ptr, End - Ptr, "%s/", GetDirectoryPath(Config.SingleHMMLFilePath));
}
else
{
Ptr += CopyString(Ptr, "%s/", Config.ProjectDir);
Ptr += CopyString(Ptr, End - Ptr, "%s/", Config.ProjectDir);
}
}
else
{
Ptr += CopyString(Ptr, "%s/", Config.TemplatesDir);
Ptr += CopyString(Ptr, End - Ptr, "%s/", Config.TemplatesDir);
}
CopyString(Ptr, "%s", Temp);
CopyString(Ptr, End - Ptr, "%s", Temp);
}
}
......@@ -1037,7 +1094,7 @@ InitTemplate(template **Template)
int
ClaimTemplate(template **Template, char *Location, int TemplateType)
{
CopyString((*Template)->Metadata.Filename, Location);
CopyString((*Template)->Metadata.Filename, sizeof((*Template)->Metadata.Filename), "%s", Location);
ConstructTemplatePath((*Template), TemplateType);
if(TemplateType == TEMPLATE_BESPOKE)
......@@ -1225,7 +1282,7 @@ ConstructURLPrefix(buffer *URLPrefix, int IncludeType, int PageType)
RewindBuffer(URLPrefix);
if(StringsDiffer(Config.RootURL, ""))
{
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.RootURL);
CopyStringToBuffer(URLPrefix, "%s/", Config.RootURL);
}
else
{
......@@ -1233,9 +1290,9 @@ ConstructURLPrefix(buffer *URLPrefix, int IncludeType, int PageType)
{
if(PageType == PAGE_PLAYER)
{
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "../");
CopyStringToBuffer(URLPrefix, "../");
}
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "../");
CopyStringToBuffer(URLPrefix, "../");
}
}
......@@ -1244,19 +1301,19 @@ ConstructURLPrefix(buffer *URLPrefix, int IncludeType, int PageType)
case INCLUDE_CSS:
if(StringsDiffer(Config.CSSDir, ""))
{
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.CSSDir);
CopyStringToBuffer(URLPrefix, "%s/", Config.CSSDir);
}
break;
case INCLUDE_Images:
if(StringsDiffer(Config.ImagesDir, ""))
{
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.ImagesDir);
CopyStringToBuffer(URLPrefix, "%s/", Config.ImagesDir);
}
break;
case INCLUDE_JS:
if(StringsDiffer(Config.JSDir, ""))
{
URLPrefix->Ptr += CopyString(URLPrefix->Ptr, "%s/", Config.JSDir);
CopyStringToBuffer(URLPrefix, "%s/", Config.JSDir);
}
break;
}
......@@ -1338,7 +1395,7 @@ SearchCredentials(buffer *CreditsMenu, bool *HasCreditsMenu, char *Person, char
ClaimBuffer(&URLPrefix, "URLPrefix", 1024);
ConstructURLPrefix(&URLPrefix, INCLUDE_Images, PAGE_PLAYER);
CopyStringToBuffer(CreditsMenu,
" <a class=\"support\" href=\"%s\" target=\"_blank\"><div class=\"support_icon\" style=\"background-image: url(%s%s);\"></div></a>\n",
" <a class=\"support\" href=\"%s\" target=\"_blank\"><div class=\"support_icon\" data-sprite=\"%s%s\"></div></a>\n",
Credentials[CredentialIndex].SupportURL,
URLPrefix.Location,
Credentials[CredentialIndex].SupportIcon);
......@@ -1353,7 +1410,7 @@ SearchCredentials(buffer *CreditsMenu, bool *HasCreditsMenu, char *Person, char
}
void
ClearString(char *String)
ClearNullTerminatedString(char *String)
{
while(*String)
{
......@@ -1364,7 +1421,7 @@ ClearString(char *String)
void
InitialString(char *Dest, char *Src)
{
ClearString(Dest);
ClearNullTerminatedString(Dest);
*Dest++ = *Src++;
while(*Src++)
{
......@@ -1382,7 +1439,7 @@ InitialString(char *Dest, char *Src)
void
GetFirstSubstring(char *Dest, char *Src)
{
ClearString(Dest);
ClearNullTerminatedString(Dest);
while(*Src && *Src != ' ')
{
*Dest++ = *Src++;
......@@ -1390,9 +1447,9 @@ GetFirstSubstring(char *Dest, char *Src)
}
void
InitialAndGetFinalString(char *Dest, char *Src)
InitialAndGetFinalString(char *Dest, int DestSize, char *Src)
{
ClearString(Dest);
ClearNullTerminatedString(Dest);
int SrcLength = StringLength(Src);
char *SrcPtr = Src + SrcLength - 1;
while(SrcPtr > Src && *SrcPtr != ' ')
......@@ -1426,7 +1483,7 @@ InitialAndGetFinalString(char *Dest, char *Src)
}
}
CopyString(Dest, SrcPtr);
CopyString(Dest, DestSize, "%s", SrcPtr);
}
bool
......@@ -1476,7 +1533,7 @@ SortAndAbbreviateSpeakers(speakers *Speakers)
switch(Attempt)
{
case 0: GetFirstSubstring(Speakers->Speaker[i].Abbreviation, Speakers->Speaker[i].Credential->CreditedName); break;
case 1: InitialAndGetFinalString(Speakers->Speaker[i].Abbreviation, Speakers->Speaker[i].Credential->CreditedName); break;
case 1: InitialAndGetFinalString(Speakers->Speaker[i].Abbreviation, sizeof(Speakers->Speaker[i].Abbreviation), Speakers->Speaker[i].Credential->CreditedName); break;
case 2: ClearCopyStringNoFormat(Speakers->Speaker[i].Abbreviation, sizeof(Speakers->Speaker[i].Abbreviation), Speakers->Speaker[i].Credential->Username); break;
}
}
......@@ -1586,14 +1643,14 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM
{
if(Ref->isbn)
{
CopyString(ReferencesArray[UniqueRefs].ID, Ref->isbn);
if(!Ref->url) { CopyString(ReferencesArray[UniqueRefs].URL, "https://isbndb.com/book/%s", Ref->isbn); }
else { CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url); }
CopyString(ReferencesArray[UniqueRefs].ID, sizeof(ReferencesArray[UniqueRefs].ID), "%s", Ref->isbn);
if(!Ref->url) { CopyString(ReferencesArray[UniqueRefs].URL, sizeof(ReferencesArray[UniqueRefs].URL), "https://isbndb.com/book/%s", Ref->isbn); }
else { CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, sizeof(ReferencesArray[UniqueRefs].URL), Ref->url); }
}
else if(Ref->url)
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, Ref->url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, Ref->url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].ID, sizeof(ReferencesArray[UniqueRefs].ID), Ref->url);
CopyStringNoFormat(ReferencesArray[UniqueRefs].URL, sizeof(ReferencesArray[UniqueRefs].URL), Ref->url);
}
else { return RC_INVALID_REFERENCE; }
......@@ -1612,56 +1669,56 @@ BuildReference(ref_info *ReferencesArray, int RefIdentifier, int UniqueRefs, HMM
{
case (REF_TITLE | REF_AUTHOR | REF_PUBLISHER):
{
CopyString(ReferencesArray[UniqueRefs].Source, "%s (%s)", Ref->author, Ref->publisher);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
CopyString(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), "%s (%s)", Ref->author, Ref->publisher);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->title);
} break;
case (REF_AUTHOR | REF_SITE | REF_PAGE):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, "%s: \"%s\"", Ref->author, Ref->page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->site);
CopyString(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), "%s: \"%s\"", Ref->author, Ref->page);
} break;
case (REF_PAGE | REF_TITLE):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->page);
} break;
case (REF_SITE | REF_PAGE):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->page);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->page);
} break;
case (REF_SITE | REF_TITLE):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->title);
} break;
case (REF_TITLE | REF_AUTHOR):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->title);
} break;
case (REF_ARTICLE | REF_AUTHOR):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->article);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->author);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->article);
} break;
case (REF_TITLE | REF_PUBLISHER):
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, Ref->publisher);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].Source, sizeof(ReferencesArray[UniqueRefs].Source), Ref->publisher);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->title);
} break;
case REF_TITLE:
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->title);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->title);
} break;
case REF_SITE:
{
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, Ref->site);
CopyStringNoFormat(ReferencesArray[UniqueRefs].RefTitle, sizeof(ReferencesArray[UniqueRefs].RefTitle), Ref->site);
} break;
default: return RC_INVALID_REFERENCE; break;
}
CopyString(ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Timecode, Anno->time);
CopyString(ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Timecode, sizeof(ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Timecode), "%s", Anno->time);
ReferencesArray[UniqueRefs].Identifier[ReferencesArray[UniqueRefs].IdentifierCount].Identifier = RefIdentifier;
return RC_SUCCESS;
}
......@@ -1695,20 +1752,20 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
int CategoryCount;
for(CategoryCount = LocalMedia->Count; CategoryCount > MediumIndex; --CategoryCount)
{
CopyString(LocalMedia->Category[CategoryCount].Marker, LocalMedia->Category[CategoryCount-1].Marker);
CopyString(LocalMedia->Category[CategoryCount].WrittenText, LocalMedia->Category[CategoryCount-1].WrittenText);
CopyString(LocalMedia->Category[CategoryCount].Marker, sizeof(LocalMedia->Category[CategoryCount].Marker), "%s", LocalMedia->Category[CategoryCount-1].Marker);
CopyString(LocalMedia->Category[CategoryCount].WrittenText, sizeof(LocalMedia->Category[CategoryCount].WrittenText), "%s", LocalMedia->Category[CategoryCount-1].WrittenText);
}
CopyString(LocalMedia->Category[CategoryCount].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(LocalMedia->Category[CategoryCount].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
CopyString(LocalMedia->Category[CategoryCount].Marker, sizeof(LocalMedia->Category[CategoryCount].Marker), "%s", CategoryMedium[CategoryMediumIndex].Medium);
CopyString(LocalMedia->Category[CategoryCount].WrittenText, sizeof(LocalMedia->Category[CategoryCount].WrittenText), "%s", CategoryMedium[CategoryMediumIndex].WrittenName);
break;
}
}
if(MediumIndex == LocalMedia->Count)
{
CopyString(LocalMedia->Category[MediumIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(LocalMedia->Category[MediumIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
CopyString(LocalMedia->Category[MediumIndex].Marker, sizeof(LocalMedia->Category[MediumIndex].Marker), "%s", CategoryMedium[CategoryMediumIndex].Medium);
CopyString(LocalMedia->Category[MediumIndex].WrittenText, sizeof(LocalMedia->Category[MediumIndex].WrittenText), "%s", CategoryMedium[CategoryMediumIndex].WrittenName);
}
++LocalMedia->Count;
......@@ -1724,20 +1781,20 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
int CategoryCount;
for(CategoryCount = GlobalMedia->Count; CategoryCount > MediumIndex; --CategoryCount)
{
CopyString(GlobalMedia->Category[CategoryCount].Marker, GlobalMedia->Category[CategoryCount-1].Marker);
CopyString(GlobalMedia->Category[CategoryCount].WrittenText, GlobalMedia->Category[CategoryCount-1].WrittenText);
CopyString(GlobalMedia->Category[CategoryCount].Marker, sizeof(GlobalMedia->Category[CategoryCount].Marker), "%s", GlobalMedia->Category[CategoryCount-1].Marker);
CopyString(GlobalMedia->Category[CategoryCount].WrittenText, sizeof(GlobalMedia->Category[CategoryCount].WrittenText), "%s", GlobalMedia->Category[CategoryCount-1].WrittenText);
}
CopyString(GlobalMedia->Category[CategoryCount].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(GlobalMedia->Category[CategoryCount].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
CopyString(GlobalMedia->Category[CategoryCount].Marker, sizeof(GlobalMedia->Category[CategoryCount].Marker), "%s", CategoryMedium[CategoryMediumIndex].Medium);
CopyString(GlobalMedia->Category[CategoryCount].WrittenText, sizeof(GlobalMedia->Category[CategoryCount].WrittenText), "%s", CategoryMedium[CategoryMediumIndex].WrittenName);
break;
}
}
if(MediumIndex == GlobalMedia->Count)
{
CopyString(GlobalMedia->Category[MediumIndex].Marker, CategoryMedium[CategoryMediumIndex].Medium);
CopyString(GlobalMedia->Category[MediumIndex].WrittenText, CategoryMedium[CategoryMediumIndex].WrittenName);
CopyString(GlobalMedia->Category[MediumIndex].Marker, sizeof(GlobalMedia->Category[MediumIndex].Marker), "%s", CategoryMedium[CategoryMediumIndex].Medium);
CopyString(GlobalMedia->Category[MediumIndex].WrittenText, sizeof(GlobalMedia->Category[MediumIndex].WrittenText), "%s", CategoryMedium[CategoryMediumIndex].WrittenName);
}
++GlobalMedia->Count;
......@@ -1756,17 +1813,17 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
int CategoryCount;
for(CategoryCount = LocalTopics->Count; CategoryCount > TopicIndex; --CategoryCount)
{
CopyString(LocalTopics->Category[CategoryCount].Marker, LocalTopics->Category[CategoryCount-1].Marker);
CopyString(LocalTopics->Category[CategoryCount].Marker, sizeof(LocalTopics->Category[CategoryCount].Marker), "%s", LocalTopics->Category[CategoryCount-1].Marker);
}
CopyString(LocalTopics->Category[CategoryCount].Marker, Marker);
CopyString(LocalTopics->Category[CategoryCount].Marker, sizeof(LocalTopics->Category[CategoryCount].Marker), "%s", Marker);
break;
}
}
if(TopicIndex == LocalTopics->Count)
{
CopyString(LocalTopics->Category[TopicIndex].Marker, Marker);
CopyString(LocalTopics->Category[TopicIndex].Marker, sizeof(LocalTopics->Category[TopicIndex].Marker), "%s", Marker);
}
++LocalTopics->Count;
......@@ -1786,10 +1843,10 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
int CategoryCount;
for(CategoryCount = GlobalTopics->Count; CategoryCount > TopicIndex; --CategoryCount)
{
CopyString(GlobalTopics->Category[CategoryCount].Marker, GlobalTopics->Category[CategoryCount-1].Marker);
CopyString(GlobalTopics->Category[CategoryCount].Marker, sizeof(GlobalTopics->Category[CategoryCount].Marker), "%s", GlobalTopics->Category[CategoryCount-1].Marker);
}
CopyString(GlobalTopics->Category[CategoryCount].Marker, Marker);
CopyString(GlobalTopics->Category[CategoryCount].Marker, sizeof(GlobalTopics->Category[CategoryCount].Marker), "%s", Marker);
break;
}
}
......@@ -1797,7 +1854,7 @@ InsertCategory(categories *GlobalTopics, categories *LocalTopics, categories *Gl
if(TopicIndex == GlobalTopics->Count)
{
CopyString(GlobalTopics->Category[TopicIndex].Marker, Marker);