@@ -6228,6 +6228,92 @@ int wolfSSH_SFTP_RecvFSetSTAT(WOLFSSH* ssh, int reqId, byte* data, word32 maxSz)
62286228}
62296229
62306230#endif /* _WIN32_WCE */
6231+
6232+ #if defined(WOLFSSH_TEST_INTERNAL ) && !defined(USE_WINDOWS_API ) && \
6233+ !defined(NO_FILESYSTEM )
6234+ /* Test-only plumbing for the forged-handle regression test in tests/regress.c.
6235+ *
6236+ * The SFTP request handlers buffer their status/handle reply into ssh->recvState
6237+ * via wolfSSH_SFTP_RecvSetSend(). When a test drives the handlers directly that
6238+ * state is not otherwise allocated, so these accessors let the test own its
6239+ * lifetime (and inspect the buffered reply) without exposing the private
6240+ * WS_SFTP_RECV_STATE type. */
6241+
6242+ /* Allocate ssh->recvState so handler replies are captured instead of leaked. */
6243+ int wolfSSH_SFTP_TestRecvStateInit (WOLFSSH * ssh )
6244+ {
6245+ if (ssh == NULL ) {
6246+ return WS_BAD_ARGUMENT ;
6247+ }
6248+ if (ssh -> recvState == NULL ) {
6249+ ssh -> recvState = (WS_SFTP_RECV_STATE * )WMALLOC (
6250+ sizeof (WS_SFTP_RECV_STATE ), ssh -> ctx -> heap , DYNTYPE_SFTP_STATE );
6251+ if (ssh -> recvState == NULL ) {
6252+ return WS_MEMORY_E ;
6253+ }
6254+ WMEMSET (ssh -> recvState , 0 , sizeof (WS_SFTP_RECV_STATE ));
6255+ }
6256+ return WS_SUCCESS ;
6257+ }
6258+
6259+ /* Return the most recent buffered reply (data + size) produced by a handler. */
6260+ const byte * wolfSSH_SFTP_TestRecvReply (WOLFSSH * ssh , word32 * sz )
6261+ {
6262+ if (ssh == NULL || ssh -> recvState == NULL ) {
6263+ if (sz != NULL ) {
6264+ * sz = 0 ;
6265+ }
6266+ return NULL ;
6267+ }
6268+ if (sz != NULL ) {
6269+ * sz = ssh -> recvState -> buffer .sz ;
6270+ }
6271+ return ssh -> recvState -> buffer .data ;
6272+ }
6273+
6274+ /* Free ssh->recvState and any buffered reply. */
6275+ void wolfSSH_SFTP_TestRecvStateFree (WOLFSSH * ssh )
6276+ {
6277+ if (ssh != NULL ) {
6278+ wolfSSH_SFTP_ClearState (ssh , STATE_ID_ALL );
6279+ }
6280+ }
6281+
6282+ /* Return the number of open file handles tracked for the session. Lets the
6283+ * handle-cap and close-failure regression tests observe the tracking list
6284+ * without exposing the private WS_FILE_LIST type. */
6285+ int wolfSSH_SFTP_TestFileHandleCount (WOLFSSH * ssh )
6286+ {
6287+ WS_FILE_LIST * cur ;
6288+ int count = 0 ;
6289+
6290+ if (ssh == NULL ) {
6291+ return 0 ;
6292+ }
6293+ for (cur = ssh -> fileList ; cur != NULL ; cur = cur -> next ) {
6294+ count ++ ;
6295+ }
6296+ return count ;
6297+ }
6298+
6299+ /* Close the underlying descriptor of the head tracked file handle out of band,
6300+ * leaving the node in the list with a now-stale fd. The next RecvClose on that
6301+ * handle will see its close() fail, exercising the path that must still drop
6302+ * the handle from the tracking list. Returns WS_SUCCESS if a node was found. */
6303+ int wolfSSH_SFTP_TestInvalidateHeadFd (WOLFSSH * ssh )
6304+ {
6305+ if (ssh == NULL || ssh -> fileList == NULL ) {
6306+ return WS_BAD_ARGUMENT ;
6307+ }
6308+ #ifdef MICROCHIP_MPLAB_HARMONY
6309+ WFCLOSE (ssh -> fs , & ssh -> fileList -> fd );
6310+ #else
6311+ WCLOSE (ssh -> fs , ssh -> fileList -> fd );
6312+ #endif
6313+ return WS_SUCCESS ;
6314+ }
6315+ #endif /* WOLFSSH_TEST_INTERNAL && !USE_WINDOWS_API && !NO_FILESYSTEM */
6316+
62316317#endif /* !NO_WOLFSSH_SERVER */
62326318
62336319
0 commit comments