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