From fd93f62fe46d910e9d84e3a58ac50e352b6e4e94 Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Thu, 21 Jul 2022 00:24:10 -0700 Subject: [PATCH] Added documentation to fs Addressed minor issues from static analysis --- meshcore/KVM/Windows/input.c | 2 +- meshcore/KVM/Windows/kvm.c | 2 +- meshcore/agentcore.c | 10 ++++++---- meshcore/wincrypto.cpp | 4 ++-- microscript/ILibDuktape_fs.c | 38 ++++++++++++++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/meshcore/KVM/Windows/input.c b/meshcore/KVM/Windows/input.c index 76759d1..c4d1fa1 100644 --- a/meshcore/KVM/Windows/input.c +++ b/meshcore/KVM/Windows/input.c @@ -579,7 +579,7 @@ int TouchAction1(unsigned char id, unsigned int flags, unsigned short x, unsigne if (g_TouchLoadLibraryState != 1) return 0; MakeTouchObject(&contact, id, (POINTER_FLAGS)flags, x, y); - if (!g_TouchInjectionCall(1, &contact)) { printf("TOUCH1ERROR: id=%d, flags=%d, x=%d, y=%d, err=%ld\r\n", id, flags, x, y, GetLastError()); return 1; } + if (!g_TouchInjectionCall(1, &contact)) { printf("TOUCH1ERROR: id=%u, flags=%u, x=%u, y=%u, err=%ld\r\n", id, flags, x, y, GetLastError()); return 1; } //printf("TOUCH: id=%d, flags=%d, x=%d, y=%d\r\n", id, flags, x, y); return 0; diff --git a/meshcore/KVM/Windows/kvm.c b/meshcore/KVM/Windows/kvm.c index 5f98b8f..fce04fe 100644 --- a/meshcore/KVM/Windows/kvm.c +++ b/meshcore/KVM/Windows/kvm.c @@ -1260,7 +1260,7 @@ int kvm_relay_setup(char *exePath, void *processPipeMgr, ILibKVM_WriteHandler wr if (ThreadRunning == 1 && g_shutdown == 0) { KVMDEBUG("kvm_relay_setup() session already exists", 0); free(parms); return 0; } kvmthread = CreateThread(NULL, 0, kvm_server_mainloop, (void*)parms, 0, 0); - CloseHandle(kvmthread); + if (kvmthread != 0) { CloseHandle(kvmthread); } return 1; } } diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index 0a39ee7..82ae754 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -818,6 +818,8 @@ void ILibDuktape_MeshAgent_Ready(ILibDuktape_EventEmitter *sender, char *eventNa #ifdef WIN32 void ILibDuktape_MeshAgent_RemoteDesktop_KVM_WriteSink_Chain(void *chain, void *user) { + if (user == NULL) { return; } + RemoteDesktop_Ptrs *ptrs = (RemoteDesktop_Ptrs*)((void**)ILibMemory_Extra(user))[0]; char *buffer = (char*)user; size_t bufferLen = ILibMemory_Size(user); @@ -915,11 +917,11 @@ ILibTransport_DoneState ILibDuktape_MeshAgent_RemoteDesktop_WriteSink(ILibDuktap #endif return ILibTransport_DoneState_COMPLETE; } -void ILibDuktape_MeshAgent_RemoteDesktop_EndSink(ILibDuktape_DuplexStream *stream, void *user) +void ILibDuktape_MeshAgent_RemoteDesktop_EndSink(ILibDuktape_DuplexStream *stream, void *ptr_user) { // Peer disconnected the data channel - RemoteDesktop_Ptrs *ptrs = (RemoteDesktop_Ptrs*)user; + RemoteDesktop_Ptrs *ptrs = (RemoteDesktop_Ptrs*)ptr_user; if (ptrs->ctx != NULL) { Duktape_Console_LogEx(ptrs->ctx, ILibDuktape_LogType_Info1, "KVM Session Ending"); @@ -1667,7 +1669,7 @@ duk_ret_t ILibDuktape_MeshAgent_ServerInfo(duk_context *ctx) #ifndef MICROSTACK_NOTLS duk_ret_t ILibDuktape_MeshAgent_GenerateCertsForDiagnosticAgent(duk_context *ctx) { - char tmp[UTIL_SHA384_HASHSIZE]; + char tmp[UTIL_SHA384_HASHSIZE] = { 0 }; struct util_cert tmpCert; #ifdef WIN32 @@ -5388,7 +5390,7 @@ int MeshAgent_AgentMode(MeshAgentHostContainer *agentHost, int paramLen, char ** if (agentHost->localdebugmode == 0) { MeshServer_Connect(agentHost); } else { - int CoreModuleLen = ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0); + CoreModuleLen = ILibSimpleDataStore_Get(agentHost->masterDb, "CoreModule", NULL, 0); if (CoreModuleLen > 4) { // There is a core module, launch it now. diff --git a/meshcore/wincrypto.cpp b/meshcore/wincrypto.cpp index be7e9db..791a9b0 100644 --- a/meshcore/wincrypto.cpp +++ b/meshcore/wincrypto.cpp @@ -149,7 +149,7 @@ wincrypto_object __fastcall wincrypto_open(int newcert, char *rootSubject) BOOL hFreeKeyNode = FALSE; BOOL status = FALSE; PBYTE subjectEncoded = NULL; - DWORD subjectEncodedSize; + DWORD subjectEncodedSize = 0; CRYPT_KEY_PROV_INFO kpi; #ifdef _CONSOLE DWORD machineflag = 0; @@ -550,7 +550,7 @@ int __fastcall wincrypto_mkCert(wincrypto_object j, char* rootSubject, wchar_t* PBYTE subject1Encoded = NULL; DWORD subject1EncodedSize; PBYTE subject2Encoded = NULL; - DWORD subject2EncodedSize; + DWORD subject2EncodedSize = 0; CRYPT_KEY_PROV_INFO kpi; BYTE* pbPolicyInfo = NULL; diff --git a/microscript/ILibDuktape_fs.c b/microscript/ILibDuktape_fs.c index cf1c59a..6403f53 100644 --- a/microscript/ILibDuktape_fs.c +++ b/microscript/ILibDuktape_fs.c @@ -1180,6 +1180,10 @@ void ILibDuktape_fs_readStream_Pause(struct ILibDuktape_readableStream *sender, UNREFERENCED_PARAMETER(user); sender->paused = 1; } + +// +// The stream.resume() contains the main processing loop. +// void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, void *user) { if (!ILibMemory_CanaryOK(user)) { return; } @@ -1196,6 +1200,7 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, data->unshiftedBytes = 0; while (sender->paused == 0 && data->bytesRead > 0 && (data->bytesLeft < 0 || data->bytesLeft > 0)) { + // The main read processing loop. we'll read as much as we can until we can't read anymore bytesToRead = data->bytesLeft < 0 ? (int)sizeof(data->buffer) : (data->bytesLeft > ((int)sizeof(data->buffer) - data->unshiftedBytes) ? (int)sizeof(data->buffer) - data->unshiftedBytes : data->bytesLeft); data->bytesRead = (int)fread(data->buffer + data->unshiftedBytes, 1, bytesToRead, data->fPtr); if (data->bytesRead > 0) @@ -1214,7 +1219,7 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, } if (sender->paused == 0 && data->bytesRead == 0) { - // We aren't paused, but the read resulted in a graceful + // We aren't paused, but the read resulted in a graceful end ILibDuktape_readableStream_WriteEnd(sender); if (data->autoClose != 0 && data->fPtr != NULL) @@ -1239,6 +1244,8 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, } data->readLoopActive = 0; } + +// Destructor called by Garbage Collector duk_ret_t ILibDuktape_fs_readStream_finalizer(duk_context *ctx) { ILibDuktape_fs_readStreamData *data; @@ -1247,6 +1254,7 @@ duk_ret_t ILibDuktape_fs_readStream_finalizer(duk_context *ctx) if (data->autoClose != 0 && data->fPtr != NULL) { + // If autoclose was specified, we need to close the descriptor if (ILibduktape_fs_CloseFD(data->ctx, data->fsObject, data->fd) != 0) { ILibDuktape_Process_UncaughtExceptionEx(data->ctx, "fs.readStream._finalizer(): Error closing FD: %d", data->fd); @@ -1257,6 +1265,8 @@ duk_ret_t ILibDuktape_fs_readStream_finalizer(duk_context *ctx) return 0; } + +// If the user can't process all the data, they call unshift() to mark some of the data as unread. The actual logic is handled in the main processing loop in the resume() function int ILibDuktape_fs_readStream_unshift(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user) { if (!ILibMemory_CanaryOK(user)) { return(unshiftBytes); } @@ -1264,6 +1274,8 @@ int ILibDuktape_fs_readStream_unshift(struct ILibDuktape_readableStream *sender, data->unshiftedBytes = unshiftBytes; return(unshiftBytes); } + +// fs.createReadStream() will create a stream.readable. The main processing loop will start when resume() is called, either directly or indirectly. duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx) { int nargs = duk_get_top(ctx); @@ -1280,6 +1292,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx) int start = 0; int end = -1; + // If an options object was specified, fetch some properties if (nargs > 1) { fd = Duktape_GetIntPropertyValue(ctx, 1, "fd", 0); @@ -1300,9 +1313,11 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx) f = ILibDuktape_fs_getFilePtr(ctx, fd); if (f == NULL) { + // Could not find a mapped descriptor return(ILibDuktape_Error(ctx, "FS CreateReadStream Error")); } + // create the stream object duk_push_object(ctx); // [readStream] ILibDuktape_WriteID(ctx, "fs.readStream"); data = (ILibDuktape_fs_readStreamData*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_fs_readStreamData)); @@ -1320,7 +1335,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx) data->bytesRead = -1; //data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data); data->stream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, ILibDuktape_fs_readStream_unshift, data); - data->stream->paused = 1; + data->stream->paused = 1; // The stream starts in the paused state... All the work is done in the resume() function //printf("readStream [start: %d, end: %d\n", start, end); @@ -1329,11 +1344,14 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx) if (start != 0) { + // If a starting position was specified, we need to seek to it fseek(f, start, SEEK_SET); } return 1; } + +// Desctructor called by Garbage Collector duk_ret_t ILibDuktape_fs_Finalizer(duk_context *ctx) { if (duk_has_prop_string(ctx, 0, FS_PIPEMANAGER_PTR) && duk_has_prop_string(ctx, 0, FS_CHAIN_PTR)) @@ -1369,6 +1387,8 @@ duk_ret_t ILibDuktape_fs_Finalizer(duk_context *ctx) return 0; } + +// Enumerate a folder path duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx) { int i = 0; @@ -1444,6 +1464,8 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx) return 1; } + +// Helper function to populate IsFile() and IsDirectory() duk_ret_t ILibDuktape_fs_statSyncEx(duk_context *ctx) { duk_push_current_function(ctx); @@ -1451,6 +1473,7 @@ duk_ret_t ILibDuktape_fs_statSyncEx(duk_context *ctx) return 1; } +// Helper function to convert file time to JS time #ifdef WIN32 char *ILibDuktape_fs_convertTime(SYSTEMTIME *st, char *dest, int destLen) #else @@ -1477,6 +1500,7 @@ char *ILibDuktape_fs_convertTime(uint64_t st, char *dest, int destLen) return(dest); } +// Fetch various attributes from the file system about a file/folder duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx) { #ifdef WIN32 @@ -1545,13 +1569,18 @@ duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx) return 1; #endif } + + #ifdef WIN32 +// Override for toString() for Windows duk_ret_t ILibDuktape_fs_readDrivesSync_result_toString(duk_context *ctx) { duk_push_this(ctx); duk_get_prop_string(ctx, -1, "name"); return 1; } + +// Pushes the result object for readDrivesSync() on Windows int ILibDuktape_fs_readDrivesSync_result_PUSH(duk_context *ctx, char *volumeName) { char driveName[1024]; @@ -1603,6 +1632,7 @@ int ILibDuktape_fs_readDrivesSync_result_PUSH(duk_context *ctx, char *volumeName } #endif +// Fetches drive information on Windows duk_ret_t ILibDuktape_fs_readDrivesSync(duk_context *ctx) { duk_push_array(ctx); @@ -1629,6 +1659,7 @@ duk_ret_t ILibDuktape_fs_readDrivesSync(duk_context *ctx) } #ifndef _NOFSWATCHER +// Closes a file watcher duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx) { ILibDuktape_fs_watcherData *data; @@ -1639,11 +1670,13 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx) data = (ILibDuktape_fs_watcherData*)Duktape_GetBuffer(ctx, -1, NULL); #if defined(WIN32) + // On windows, we have to cancel pending I/O on the handle int r = CancelIo(data->h); ILibChain_RemoveWaitHandle(data->chain, data->overlapped.hEvent); CloseHandle(data->h); data->h = NULL; #elif defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD) + // On Linux, we have to remove the watcher on the descriptor ILibHashtable_Remove(data->linuxWatcher->watchTable, data->wd.p, NULL, 0); if (inotify_rm_watch(data->linuxWatcher->fd, data->wd.i) != 0) { ILibRemoteLogging_printf(ILibChainGetLogger(Duktape_GetChain(ctx)), ILibRemoteLogging_Modules_Agent_GuardPost | ILibRemoteLogging_Modules_ConsolePrint, ILibRemoteLogging_Flags_VerbosityLevel_1, "FSWatcher.close(): Error removing wd[%d] from fd[%d]", data->wd.i, data->linuxWatcher->fd); } else @@ -1652,6 +1685,7 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx) } data->wd.p = NULL; #elif defined(__APPLE__) + // On macOS we have to signal to the kevent() loop to exit duk_push_this(ctx); duk_get_prop_string(ctx, -1, FS_WATCHER_2_FS); duk_get_prop_string(ctx, -1, FS_NOTIFY_DISPATCH_PTR);