@@ -6124,6 +6124,92 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
61246124}
61256125
61266126#endif /* _WIN32_WCE */
6127+
6128+ #if defined(WOLFSSH_TEST_INTERNAL ) && !defined(USE_WINDOWS_API ) && \
6129+ !defined(NO_FILESYSTEM )
6130+ /* Test-only plumbing for the forged-handle regression test in tests/regress.c.
6131+ *
6132+ * The SFTP request handlers buffer their status/handle reply into ssh->recvState
6133+ * via wolfSSH_SFTP_RecvSetSend(). When a test drives the handlers directly that
6134+ * state is not otherwise allocated, so these accessors let the test own its
6135+ * lifetime (and inspect the buffered reply) without exposing the private
6136+ * WS_SFTP_RECV_STATE type. */
6137+
6138+ /* Allocate ssh->recvState so handler replies are captured instead of leaked. */
6139+ int wolfSSH_SFTP_TestRecvStateInit (WOLFSSH * ssh )
6140+ {
6141+ if (ssh == NULL ) {
6142+ return WS_BAD_ARGUMENT ;
6143+ }
6144+ if (ssh -> recvState == NULL ) {
6145+ ssh -> recvState = (WS_SFTP_RECV_STATE * )WMALLOC (
6146+ sizeof (WS_SFTP_RECV_STATE ), ssh -> ctx -> heap , DYNTYPE_SFTP_STATE );
6147+ if (ssh -> recvState == NULL ) {
6148+ return WS_MEMORY_E ;
6149+ }
6150+ WMEMSET (ssh -> recvState , 0 , sizeof (WS_SFTP_RECV_STATE ));
6151+ }
6152+ return WS_SUCCESS ;
6153+ }
6154+
6155+ /* Return the most recent buffered reply (data + size) produced by a handler. */
6156+ const byte * wolfSSH_SFTP_TestRecvReply (WOLFSSH * ssh , word32 * sz )
6157+ {
6158+ if (ssh == NULL || ssh -> recvState == NULL ) {
6159+ if (sz != NULL ) {
6160+ * sz = 0 ;
6161+ }
6162+ return NULL ;
6163+ }
6164+ if (sz != NULL ) {
6165+ * sz = ssh -> recvState -> buffer .sz ;
6166+ }
6167+ return ssh -> recvState -> buffer .data ;
6168+ }
6169+
6170+ /* Free ssh->recvState and any buffered reply. */
6171+ void wolfSSH_SFTP_TestRecvStateFree (WOLFSSH * ssh )
6172+ {
6173+ if (ssh != NULL ) {
6174+ wolfSSH_SFTP_ClearState (ssh , STATE_ID_ALL );
6175+ }
6176+ }
6177+
6178+ /* Return the number of open file handles tracked for the session. Lets the
6179+ * handle-cap and close-failure regression tests observe the tracking list
6180+ * without exposing the private WS_FILE_LIST type. */
6181+ int wolfSSH_SFTP_TestFileHandleCount (WOLFSSH * ssh )
6182+ {
6183+ WS_FILE_LIST * cur ;
6184+ int count = 0 ;
6185+
6186+ if (ssh == NULL ) {
6187+ return 0 ;
6188+ }
6189+ for (cur = ssh -> fileList ; cur != NULL ; cur = cur -> next ) {
6190+ count ++ ;
6191+ }
6192+ return count ;
6193+ }
6194+
6195+ /* Close the underlying descriptor of the head tracked file handle out of band,
6196+ * leaving the node in the list with a now-stale fd. The next RecvClose on that
6197+ * handle will see its close() fail, exercising the path that must still drop
6198+ * the handle from the tracking list. Returns WS_SUCCESS if a node was found. */
6199+ int wolfSSH_SFTP_TestInvalidateHeadFd (WOLFSSH * ssh )
6200+ {
6201+ if (ssh == NULL || ssh -> fileList == NULL ) {
6202+ return WS_BAD_ARGUMENT ;
6203+ }
6204+ #ifdef MICROCHIP_MPLAB_HARMONY
6205+ WFCLOSE (ssh -> fs , & ssh -> fileList -> fd );
6206+ #else
6207+ WCLOSE (ssh -> fs , ssh -> fileList -> fd );
6208+ #endif
6209+ return WS_SUCCESS ;
6210+ }
6211+ #endif /* WOLFSSH_TEST_INTERNAL && !USE_WINDOWS_API && !NO_FILESYSTEM */
6212+
61276213#endif /* !NO_WOLFSSH_SERVER */
61286214
61296215
0 commit comments