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