@@ -4983,6 +4983,110 @@ static int test_Errors(void)
49834983 return result ;
49844984}
49854985
4986+ #if defined(WOLFSSH_SFTP ) && defined(WOLFSSH_TEST_INTERNAL )
4987+ /* Inject a crafted SFTP NAME header declaring an on-wire payload length of
4988+ * 'wireLen' into a channel, drive wolfSSH_SFTP_DoName, and report ssh->error
4989+ * via outErr. Only the 9-byte header is needed: the NAME size bound is
4990+ * checked before the message body is read. Returns 0 on setup success. */
4991+ static int sftpDoNameInjectErr (word32 wireLen , int * outErr )
4992+ {
4993+ WOLFSSH_CTX * ctx = NULL ;
4994+ WOLFSSH * ssh = NULL ;
4995+ WOLFSSH_CHANNEL * ch = NULL ;
4996+ byte hdr [LENGTH_SZ + MSG_ID_SZ + UINT32_SZ ];
4997+ int result = 0 ;
4998+
4999+ ctx = wolfSSH_CTX_new (WOLFSSH_ENDPOINT_CLIENT , NULL );
5000+ if (ctx == NULL )
5001+ return -560 ;
5002+ ssh = wolfSSH_new (ctx );
5003+ if (ssh == NULL ) {
5004+ wolfSSH_CTX_free (ctx );
5005+ return -561 ;
5006+ }
5007+
5008+ ch = ChannelNew (ssh , ID_CHANTYPE_SESSION , 128 , 128 );
5009+ if (ch == NULL ) {
5010+ result = -562 ;
5011+ goto done ;
5012+ }
5013+ if (ChannelAppend (ssh , ch ) != WS_SUCCESS ) {
5014+ ChannelDelete (ch , ssh -> ctx -> heap );
5015+ result = -563 ;
5016+ goto done ;
5017+ }
5018+
5019+ /* SFTP header: [uint32 length][byte type][uint32 reqId]. */
5020+ hdr [0 ] = (byte )(wireLen >> 24 );
5021+ hdr [1 ] = (byte )(wireLen >> 16 );
5022+ hdr [2 ] = (byte )(wireLen >> 8 );
5023+ hdr [3 ] = (byte )(wireLen );
5024+ hdr [LENGTH_SZ ] = WOLFSSH_FTP_NAME ;
5025+ hdr [LENGTH_SZ + MSG_ID_SZ + 0 ] = 0 ;
5026+ hdr [LENGTH_SZ + MSG_ID_SZ + 1 ] = 0 ;
5027+ hdr [LENGTH_SZ + MSG_ID_SZ + 2 ] = 0 ;
5028+ hdr [LENGTH_SZ + MSG_ID_SZ + 3 ] = 0 ;
5029+
5030+ /* Leave reqId non-matching so an in-bound header exits at the request-id
5031+ * check without setting WS_BUFFER_E. */
5032+ ssh -> reqId = 0xFFFFFFFF ;
5033+ ssh -> error = WS_SUCCESS ;
5034+
5035+ if (wolfSSH_TestChannelPutData (ch , hdr , (word32 )sizeof (hdr ))
5036+ != WS_SUCCESS ) {
5037+ result = -564 ;
5038+ goto done ;
5039+ }
5040+
5041+ * outErr = wolfSSH_TestSftpDoName (ssh );
5042+
5043+ done :
5044+ wolfSSH_free (ssh );
5045+ wolfSSH_CTX_free (ctx );
5046+ return result ;
5047+ }
5048+
5049+ /* Verify wolfSSH_SFTP_DoName rejects a NAME message larger than
5050+ * WOLFSSH_MAX_SFTP_NAME and accepts one at the limit. SFTP_GetHeader
5051+ * returns the wire length minus the type and request-id fields, so the
5052+ * reported maxSz is wireLen - (UINT32_SZ + MSG_ID_SZ). */
5053+ static int test_SftpDoName_sizeBound (void )
5054+ {
5055+ word32 overhead = UINT32_SZ + MSG_ID_SZ ;
5056+ int err = 0 ;
5057+ int result ;
5058+
5059+ /* maxSz = WOLFSSH_MAX_SFTP_NAME + 1 -> over the bound, rejected. */
5060+ err = WS_SUCCESS ;
5061+ result = sftpDoNameInjectErr (WOLFSSH_MAX_SFTP_NAME + overhead + 1 , & err );
5062+ if (result != 0 )
5063+ return result ;
5064+ if (err != WS_BUFFER_E )
5065+ return -570 ;
5066+
5067+ /* maxSz = WOLFSSH_MAX_SFTP_NAME -> at the bound, not rejected (exits at
5068+ * the request-id check instead). */
5069+ err = WS_SUCCESS ;
5070+ result = sftpDoNameInjectErr (WOLFSSH_MAX_SFTP_NAME + overhead , & err );
5071+ if (result != 0 )
5072+ return result ;
5073+ if (err == WS_BUFFER_E )
5074+ return -571 ;
5075+
5076+ /* A wire length above INT_MAX makes SFTP_GetHeader's int result wrap
5077+ * non-positive; this must be reported as a size error, not a silent
5078+ * NULL with WS_SUCCESS. */
5079+ err = WS_SUCCESS ;
5080+ result = sftpDoNameInjectErr (0x80000000U + overhead , & err );
5081+ if (result != 0 )
5082+ return result ;
5083+ if (err != WS_BUFFER_E )
5084+ return -572 ;
5085+
5086+ return 0 ;
5087+ }
5088+ #endif /* WOLFSSH_SFTP && WOLFSSH_TEST_INTERNAL */
5089+
49865090int wolfSSH_UnitTest (int argc , char * * argv )
49875091{
49885092 int testResult = 0 , unitResult = 0 ;
@@ -5057,6 +5161,12 @@ int wolfSSH_UnitTest(int argc, char** argv)
50575161 unitResult = test_SendChannelData_eofTxd ();
50585162 printf ("SendChannelData_eofTxd: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
50595163 testResult = testResult || unitResult ;
5164+
5165+ #ifdef WOLFSSH_SFTP
5166+ unitResult = test_SftpDoName_sizeBound ();
5167+ printf ("SftpDoName_sizeBound: %s\n" , (unitResult == 0 ? "SUCCESS" : "FAILED" ));
5168+ testResult = testResult || unitResult ;
5169+ #endif
50605170#if !defined(WOLFSSH_NO_RSA )
50615171 unitResult = test_RsaVerify_BadDigest ();
50625172 printf ("RsaVerify_BadDigest: %s\n" ,
0 commit comments