From 1280142d4574ac25034c4befbbbd35c8b76e54a4 Mon Sep 17 00:00:00 2001 From: Matt Mascarenhas Date: Fri, 13 Jan 2023 12:01:26 +0000 Subject: [PATCH] cinera.c: Clean up string copy functions This commit replaces ClearCopyStringNoFormat() with ClearCopyStringNoFormatOrTerminate(). All calls to that function passed an implicitly 0-terminated string as the destination, meaning that we don't need to 0-terminate them and, in not doing, we free up a byte to store data. It also deduplicates code as CopyBytes(), and does a little bounds checking before actually trying to copy. --- cinera/cinera.c | 169 ++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 105 deletions(-) diff --git a/cinera/cinera.c b/cinera/cinera.c index c3e9530..6ebefc2 100644 --- a/cinera/cinera.c +++ b/cinera/cinera.c @@ -23,7 +23,7 @@ typedef struct version CINERA_APP_VERSION = { .Major = 0, .Minor = 10, - .Patch = 20 + .Patch = 21 }; #define __USE_XOPEN2K8 // NOTE(matt): O_NOFOLLOW @@ -478,14 +478,20 @@ typedef struct uint64_t Length; } string; +int +CopyBytes(char *Dest, char *Src, int Count) +{ + for(int i = 0; i < Count; ++i) + { + Dest[i] = Src[i]; + } + return Count; +} + int CopyStringToBarePtr(char *Dest, string Src) { - for(int i = 0; i < Src.Length; ++i) - { - *Dest++ = Src.Base[i]; - } - return Src.Length; + return CopyBytes(Dest, Src.Base, Src.Length); } typedef struct @@ -4275,10 +4281,7 @@ CopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, string String) "%.*s\n", LineNumber, DestSize, String.Length, (int)String.Length, String.Base); __asm__("int3"); } - for(int i = 0; i < String.Length; ++i) - { - *Dest++ = String.Base[i]; - } + Dest += CopyBytes(Dest, String.Base, String.Length); *Dest = '\0'; return String.Length; } @@ -4295,31 +4298,7 @@ ClearCopyStringNoFormatOrTerminate_(int LineNumber, char *Dest, int DestSize, st } Clear(Dest, DestSize); - for(int i = 0; i < String.Length; ++i) - { - *Dest++ = String.Base[i]; - } - return String.Length; -} - -#define ClearCopyStringNoFormat(Dest, DestSize, String) ClearCopyStringNoFormat_(__LINE__, Dest, DestSize, String) -int -ClearCopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, string String) -{ - if(String.Length + 1 > DestSize) - { - printf("ClearCopyStringNoFormat() call on line %d has been passed a buffer too small (%d bytes) to contain null-terminated %ld(+1)-character string:\n" - "%.*s\n", LineNumber, DestSize, String.Length, (int)String.Length, String.Base); - __asm__("int3"); - } - - Clear(Dest, DestSize); - for(int i = 0; i < String.Length; ++i) - { - *Dest++ = String.Base[i]; - } - *Dest = '\0'; - return String.Length; + return CopyBytes(Dest, String.Base, String.Length); } // TODO(matt): Maybe do a version of this that takes a string as a Terminator @@ -4327,21 +4306,20 @@ ClearCopyStringNoFormat_(int LineNumber, char *Dest, int DestSize, string String int CopyStringNoFormatT_(int LineNumber, char *Dest, int DestSize, char *String, char Terminator) { - int Length = 0; - char *Start = String; - while(*String != Terminator) + int BytesToWrite = 0; + while(String[BytesToWrite] && String[BytesToWrite] != Terminator) { - *Dest++ = *String++; - ++Length; + ++BytesToWrite; } - if(Length >= DestSize) + if(BytesToWrite >= 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); + "%.*s\n", LineNumber, DestSize, Terminator == 0 ? '0' : Terminator, BytesToWrite, BytesToWrite, String); __asm__("int3"); } + Dest += CopyBytes(Dest, String, BytesToWrite); *Dest = '\0'; - return Length; + return BytesToWrite; } #define CopyStringToBuffer(Dest, Format, ...) CopyStringToBuffer_(__LINE__, Dest, Format, ##__VA_ARGS__) @@ -4418,10 +4396,7 @@ CopyStringToBufferNoFormat_(int LineNumber, buffer *Dest, string String) "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, String.Length, (int)String.Length, String.Base); __asm__("int3"); } - for(int i = 0; i < String.Length; ++i) - { - *Dest->Ptr++ = String.Base[i]; - } + Dest->Ptr += CopyBytes(Dest->Ptr, String.Base, String.Length); *Dest->Ptr = '\0'; } @@ -4435,27 +4410,20 @@ CopyStringToBufferNoTerminate_(int LineNumber, buffer *Dest, string Src) "%.*s\n", BufferIDStrings[Dest->ID], LineNumber, Src.Length, (int)Src.Length, Src.Base); __asm__("int3"); } - for(int i = 0; i < Src.Length; ++i) - { - *Dest->Ptr++ = Src.Base[i]; - } + Dest->Ptr += CopyBytes(Dest->Ptr, Src.Base, Src.Length); } #define CopyStringToBufferNoFormatL(Dest, Length, String) CopyStringToBufferNoFormatL_(__LINE__, Dest, Length, String) void CopyStringToBufferNoFormatL_(int LineNumber, buffer *Dest, int Length, char *String) { - char *Start = String; - for(int i = 0; i < Length; ++i) + if(Dest->Ptr - Dest->Location + Length + 1 >= Dest->Size) { - *Dest->Ptr++ = *String++; - } - if(Dest->Ptr - Dest->Location >= Dest->Size) - { - fprintf(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld-character string:\n" - "%s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Start), Start); + fprintf(stderr, "CopyStringToBufferNoFormat(%s) call on line %d cannot accommodate %ld(+1)-character string:\n" + "%s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(String), String); __asm__("int3"); } + Dest->Ptr += CopyBytes(Dest->Ptr, String, Length); *Dest->Ptr = '\0'; } @@ -4599,10 +4567,7 @@ CopyBuffer_(int LineNumber, buffer *Dest, buffer *Src) fprintf(stderr, "CopyBuffer(%s) call on line %d cannot accommodate %ld(+1)-character %s\n", BufferIDStrings[Dest->ID], LineNumber, StringLength(Src->Location), BufferIDStrings[Src->ID]); __asm__("int3"); } - for(int i = 0; i < Src->Ptr - Src->Location; ++i) - { - *Dest->Ptr++ = Src->Location[i]; - } + Dest->Ptr += CopyBytes(Dest->Ptr, Src->Location, Src->Ptr - Src->Location); *Dest->Ptr = '\0'; } @@ -4662,10 +4627,7 @@ CopyLandmarkedBuffer_(int LineNumber, buffer *Dest, buffer *Src, uint32_t *PrevS if(PrevStartLinkOffset) { *PrevStartLinkOffset += Dest->Ptr - Dest->Location; } OffsetLandmarks(Dest, Src, PageType); - for(int i = 0; i < Src->Ptr - Src->Location; ++i) - { - *Dest->Ptr++ = Src->Location[i]; - } + Dest->Ptr += CopyBytes(Dest->Ptr, Src->Location, Src->Ptr - Src->Location); *Dest->Ptr = '\0'; } @@ -4679,10 +4641,7 @@ CopyBufferSized_(int LineNumber, buffer *Dest, buffer *Src, uint64_t Size) fprintf(stderr, "CopyBufferSized(%s) call on line %d cannot accommodate %ld-character %s\n", BufferIDStrings[Dest->ID], LineNumber, Size, BufferIDStrings[Src->ID]); __asm__("int3"); } - for(int i = 0; i < Size; ++i) - { - *Dest->Ptr++ = Src->Location[i]; - } + Dest->Ptr += CopyBytes(Dest->Ptr, Src->Location, Size); } void @@ -6659,7 +6618,7 @@ UpdateAssetInDB(asset *Asset) StoredAsset.Height = Asset->Dimensions.Height; StoredAsset.Associated = Asset->Associated; - ClearCopyStringNoFormat(StoredAsset.Filename, sizeof(StoredAsset.Filename), Wrap0i(Asset->Filename)); + ClearCopyStringNoFormatOrTerminate(StoredAsset.Filename, sizeof(StoredAsset.Filename), Wrap0i(Asset->Filename)); fwrite(&StoredAsset, sizeof(StoredAsset), 1, DB.Metadata.File.Handle); AccumulateFileEditSize(&DB.Metadata, sizeof(StoredAsset)); @@ -10995,7 +10954,7 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF } else { - ClearCopyStringNoFormat(CollationBuffers->Title, sizeof(CollationBuffers->Title), Wrap0(HMML.metadata.title)); + ClearCopyStringNoFormatOrTerminate(CollationBuffers->Title, sizeof(CollationBuffers->Title), Wrap0(HMML.metadata.title)); Title = Wrap0(HMML.metadata.title); } @@ -11084,7 +11043,7 @@ HMMLToBuffers(buffers *CollationBuffers, template *BespokeTemplate, string BaseF } else { - ClearCopyStringNoFormat(N->WorkingThis.Number, sizeof(N->WorkingThis.Number), Wrap0(HMML.metadata.number)); + ClearCopyStringNoFormatOrTerminate(N->WorkingThis.Number, sizeof(N->WorkingThis.Number), Wrap0(HMML.metadata.number)); } } @@ -13035,9 +12994,9 @@ InsertIntoDB(neighbourhood *N, buffers *CollationBuffers, template *BespokeTempl VideoIsPrivate = TRUE; } - ClearCopyStringNoFormat(N->WorkingThis.HMMLBaseFilename, sizeof(N->WorkingThis.HMMLBaseFilename), BaseFilename); + ClearCopyStringNoFormatOrTerminate(N->WorkingThis.HMMLBaseFilename, sizeof(N->WorkingThis.HMMLBaseFilename), BaseFilename); - if(!VideoIsPrivate) { ClearCopyStringNoFormat(N->WorkingThis.Title, sizeof(N->WorkingThis.Title), Wrap0i(CollationBuffers->Title)); } + if(!VideoIsPrivate) { ClearCopyStringNoFormatOrTerminate(N->WorkingThis.Title, sizeof(N->WorkingThis.Title), Wrap0i(CollationBuffers->Title)); } if(!DB.File.Buffer.Location) { @@ -15445,11 +15404,11 @@ UpgradeDB(int OriginalDBVersion) DB.AssetsBlock.BlockID = FOURCC("ASET"); DB.AssetsBlock.Count = 0; - ClearCopyStringNoFormat(DB.AssetsBlock.RootDir, sizeof(DB.AssetsBlock.RootDir), Config->AssetsRootDir); - ClearCopyStringNoFormat(DB.AssetsBlock.RootURL, sizeof(DB.AssetsBlock.RootURL), Config->AssetsRootURL); - ClearCopyStringNoFormat(DB.AssetsBlock.CSSDir, sizeof(DB.AssetsBlock.CSSDir), Config->CSSDir); - ClearCopyStringNoFormat(DB.AssetsBlock.ImagesDir, sizeof(DB.AssetsBlock.ImagesDir), Config->ImagesDir); - ClearCopyStringNoFormat(DB.AssetsBlock.JSDir, sizeof(DB.AssetsBlock.JSDir), Config->JSDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.RootDir, sizeof(DB.AssetsBlock.RootDir), Config->AssetsRootDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.RootURL, sizeof(DB.AssetsBlock.RootURL), Config->AssetsRootURL); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.CSSDir, sizeof(DB.AssetsBlock.CSSDir), Config->CSSDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.ImagesDir, sizeof(DB.AssetsBlock.ImagesDir), Config->ImagesDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.JSDir, sizeof(DB.AssetsBlock.JSDir), Config->JSDir); ++DB.Header.BlockCount; OpenFileForWriting(&DB.Metadata.File); @@ -15497,7 +15456,7 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) char *OldPlayerDirectory = ConstructDirectoryPath(&OldBaseDir, &OldPlayerLocation, 0); db_header_project NewProjectHeader = *N->Project; - ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir); + ClearCopyStringNoFormatOrTerminate(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir); string NewBaseDir = Wrap0i(NewProjectHeader.BaseDir); char *NewPlayerDirectory = ConstructDirectoryPath(&NewBaseDir, &CurrentProject->PlayerLocation, 0); @@ -15521,7 +15480,7 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) } Free(OldPlayerDirectory); - ClearCopyStringNoFormat(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation), CurrentProject->PlayerLocation); + ClearCopyStringNoFormatOrTerminate(N->Project->PlayerLocation, sizeof(N->Project->PlayerLocation), CurrentProject->PlayerLocation); HasNewPlayerLocation = TRUE; } @@ -15533,8 +15492,8 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) char *OldSearchDirectory = ConstructDirectoryPath(&OldBaseDir, &OldSearchLocation, 0); db_header_project NewProjectHeader = *N->Project; - ClearCopyStringNoFormat(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir); - ClearCopyStringNoFormat(NewProjectHeader.SearchLocation, sizeof(NewProjectHeader.SearchLocation), CurrentProject->SearchLocation); + ClearCopyStringNoFormatOrTerminate(NewProjectHeader.BaseDir, sizeof(NewProjectHeader.BaseDir), CurrentProject->BaseDir); + ClearCopyStringNoFormatOrTerminate(NewProjectHeader.SearchLocation, sizeof(NewProjectHeader.SearchLocation), CurrentProject->SearchLocation); string NewBaseDir = Wrap0i(NewProjectHeader.BaseDir); string NewSearchLocation = Wrap0i(NewProjectHeader.SearchLocation); @@ -15569,13 +15528,13 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) remove(OldSearchDirectory); Free(OldSearchDirectory); - ClearCopyStringNoFormat(N->Project->SearchLocation, sizeof(N->Project->SearchLocation), CurrentProject->SearchLocation); + ClearCopyStringNoFormatOrTerminate(N->Project->SearchLocation, sizeof(N->Project->SearchLocation), CurrentProject->SearchLocation); HasNewSearchLocation = TRUE; } if(StringsDiffer(CurrentProject->BaseDir, Wrap0i(N->Project->BaseDir))) { - ClearCopyStringNoFormat(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir); + ClearCopyStringNoFormatOrTerminate(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir); OpenFileForWriting(&DB.Metadata.File); WriteFromByteToEnd(&DB.Metadata.File, 0); CycleSignpostedFile(&DB.Metadata); @@ -15585,7 +15544,7 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) if(StringsDiffer(CurrentProject->BaseURL, Wrap0i(N->Project->BaseURL))) { - ClearCopyStringNoFormat(N->Project->BaseURL, sizeof(N->Project->BaseURL), CurrentProject->BaseURL); + ClearCopyStringNoFormatOrTerminate(N->Project->BaseURL, sizeof(N->Project->BaseURL), CurrentProject->BaseURL); OpenFileForWriting(&DB.Metadata.File); WriteFromByteToEnd(&DB.Metadata.File, 0); CycleSignpostedFile(&DB.Metadata); @@ -15596,8 +15555,8 @@ DeleteDeadDBEntries(neighbourhood *N, bool *Modified) if(HasNewPlayerLocation || HasNewSearchLocation) { if(!(OpenFileForWriting(&DB.Metadata.File))) { FreeBuffer(&DB.Metadata.File.Buffer); return RC_ERROR_FILE; } - ClearCopyStringNoFormat(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir); - ClearCopyStringNoFormat(N->Project->BaseURL, sizeof(N->Project->BaseURL), CurrentProject->BaseURL); + ClearCopyStringNoFormatOrTerminate(N->Project->BaseDir, sizeof(N->Project->BaseDir), CurrentProject->BaseDir); + ClearCopyStringNoFormatOrTerminate(N->Project->BaseURL, sizeof(N->Project->BaseURL), CurrentProject->BaseURL); fwrite(DB.Metadata.File.Buffer.Location, DB.Metadata.File.Buffer.Size, 1, DB.Metadata.File.Handle); CycleSignpostedFile(&DB.Metadata); UpdateNeighbourhoodPointers(N, &DB.Metadata.Signposts); @@ -15670,7 +15629,7 @@ SyncDBWithInput(neighbourhood *N, buffers *CollationBuffers, template *BespokeTe bool Modified = FALSE; if(StringsDiffer(CurrentProject->Title, Wrap0i(N->Project->Title))) { - ClearCopyStringNoFormat(N->Project->Title, sizeof(N->Project->Title), CurrentProject->Title); + ClearCopyStringNoFormatOrTerminate(N->Project->Title, sizeof(N->Project->Title), CurrentProject->Title); OpenFileForWriting(&DB.Metadata.File); WriteFromByteToEnd(&DB.Metadata.File, 0); CycleSignpostedFile(&DB.Metadata); @@ -15680,7 +15639,7 @@ SyncDBWithInput(neighbourhood *N, buffers *CollationBuffers, template *BespokeTe if(StringsDiffer(CurrentProject->Theme, Wrap0i(N->Project->Theme))) { - ClearCopyStringNoFormat(N->Project->Theme, sizeof(N->Project->Theme), CurrentProject->Theme); + ClearCopyStringNoFormatOrTerminate(N->Project->Theme, sizeof(N->Project->Theme), CurrentProject->Theme); OpenFileForWriting(&DB.Metadata.File); WriteFromByteToEnd(&DB.Metadata.File, 0); CycleSignpostedFile(&DB.Metadata); @@ -15690,7 +15649,7 @@ SyncDBWithInput(neighbourhood *N, buffers *CollationBuffers, template *BespokeTe if(StringsDiffer(CurrentProject->Numbering.Unit, Wrap0i(N->Project->Unit))) { - ClearCopyStringNoFormat(N->Project->Unit, sizeof(N->Project->Unit), CurrentProject->Numbering.Unit); + ClearCopyStringNoFormatOrTerminate(N->Project->Unit, sizeof(N->Project->Unit), CurrentProject->Numbering.Unit); OpenFileForWriting(&DB.Metadata.File); WriteFromByteToEnd(&DB.Metadata.File, 0); CycleSignpostedFile(&DB.Metadata); @@ -15922,18 +15881,18 @@ InitDB(void) DB.Header.BlockCount = 0; DB.ProjectsBlock.BlockID = FOURCC("PROJ"); - ClearCopyStringNoFormat(DB.ProjectsBlock.GlobalSearchDir, sizeof(DB.ProjectsBlock.GlobalSearchDir), Config->GlobalSearchDir); - ClearCopyStringNoFormat(DB.ProjectsBlock.GlobalSearchURL, sizeof(DB.ProjectsBlock.GlobalSearchURL), Config->GlobalSearchURL); + ClearCopyStringNoFormatOrTerminate(DB.ProjectsBlock.GlobalSearchDir, sizeof(DB.ProjectsBlock.GlobalSearchDir), Config->GlobalSearchDir); + ClearCopyStringNoFormatOrTerminate(DB.ProjectsBlock.GlobalSearchURL, sizeof(DB.ProjectsBlock.GlobalSearchURL), Config->GlobalSearchURL); DB.ProjectsBlock.Count = 0; ++DB.Header.BlockCount; DB.AssetsBlock.BlockID = FOURCC("ASET"); DB.AssetsBlock.Count = 0; - ClearCopyStringNoFormat(DB.AssetsBlock.RootDir, sizeof(DB.AssetsBlock.RootDir), Config->AssetsRootDir); - ClearCopyStringNoFormat(DB.AssetsBlock.RootURL, sizeof(DB.AssetsBlock.RootURL), Config->AssetsRootURL); - ClearCopyStringNoFormat(DB.AssetsBlock.CSSDir, sizeof(DB.AssetsBlock.CSSDir), Config->CSSDir); - ClearCopyStringNoFormat(DB.AssetsBlock.ImagesDir, sizeof(DB.AssetsBlock.ImagesDir), Config->ImagesDir); - ClearCopyStringNoFormat(DB.AssetsBlock.JSDir, sizeof(DB.AssetsBlock.JSDir), Config->JSDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.RootDir, sizeof(DB.AssetsBlock.RootDir), Config->AssetsRootDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.RootURL, sizeof(DB.AssetsBlock.RootURL), Config->AssetsRootURL); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.CSSDir, sizeof(DB.AssetsBlock.CSSDir), Config->CSSDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.ImagesDir, sizeof(DB.AssetsBlock.ImagesDir), Config->ImagesDir); + ClearCopyStringNoFormatOrTerminate(DB.AssetsBlock.JSDir, sizeof(DB.AssetsBlock.JSDir), Config->JSDir); ++DB.Header.BlockCount; char *DatabaseLocation0 = MakeString0("l", &Config->DatabaseLocation); @@ -16735,13 +16694,13 @@ SyncGlobalPagesWithInput(neighbourhood *N, buffers *CollationBuffers) char *StoredGlobalSearchDir0 = MakeString0("l", &StoredGlobalSearchDir); if(StringsDiffer(StoredGlobalSearchDir, Config->GlobalSearchDir)) { - ClearCopyStringNoFormat(ProjectsBlock->GlobalSearchDir, sizeof(ProjectsBlock->GlobalSearchDir), Config->GlobalSearchDir); + ClearCopyStringNoFormatOrTerminate(ProjectsBlock->GlobalSearchDir, sizeof(ProjectsBlock->GlobalSearchDir), Config->GlobalSearchDir); WriteEntireDatabase(N); } if(StringsDiffer(StoredGlobalSearchURL, Config->GlobalSearchURL)) { - ClearCopyStringNoFormat(ProjectsBlock->GlobalSearchURL, sizeof(ProjectsBlock->GlobalSearchURL), Config->GlobalSearchURL); + ClearCopyStringNoFormatOrTerminate(ProjectsBlock->GlobalSearchURL, sizeof(ProjectsBlock->GlobalSearchURL), Config->GlobalSearchURL); WriteEntireDatabase(N); } @@ -17257,8 +17216,8 @@ MonitorFilesystem(neighbourhood *N, buffers *CollationBuffers, template *Bespoke sleep(1); // NOTE(matt): Give any remaining events time to occur struct inotify_event EventN = *Event; - char EventNName[Event->len + 1]; - ClearCopyStringNoFormat(EventNName, sizeof(EventNName), Wrap0(Event->name)); + char EventNName[Event->len]; + ClearCopyStringNoFormatOrTerminate(EventNName, sizeof(EventNName), Wrap0(Event->name)); char *EventSlot1 = Events.Location + sizeof(struct inotify_event) + Event->len; @@ -17268,7 +17227,7 @@ MonitorFilesystem(neighbourhood *N, buffers *CollationBuffers, template *Bespoke BytesRead = sizeof(struct inotify_event) + EventN.len + NewBytesRead; struct inotify_event *Event0 = (struct inotify_event *)Events.Location; *Event0 = EventN; - CopyStringNoFormat(Event0->name, Event0->len, Wrap0(EventNName)); + ClearCopyStringNoFormatOrTerminate(Event0->name, Event0->len, Wrap0i(EventNName)); Event = Event0; Events.Ptr = Events.Location; #if DEBUG_EVENTS