fixed zmodem corruption issues (#10587)

This commit is contained in:
Eugene
2025-07-23 09:31:01 +02:00
committed by GitHub
parent 7e1905c32c
commit 3c17654180

View File

@@ -27,7 +27,7 @@ class ZModemMiddleware extends SessionMiddleware {
this.logger = log.create('zmodem') this.logger = log.create('zmodem')
this.sentry = new ZModem.Sentry({ this.sentry = new ZModem.Sentry({
to_terminal: data => { to_terminal: data => {
if (this.isActive) { if (this.isActive && this.activeSession) {
this.outputToTerminal.next(Buffer.from(data)) this.outputToTerminal.next(Buffer.from(data))
} }
}, },
@@ -42,25 +42,32 @@ class ZModemMiddleware extends SessionMiddleware {
}, },
on_retract: () => { on_retract: () => {
this.showMessage('transfer cancelled') this.showMessage('transfer cancelled')
this.activeSession = null
this.isActive = false
}, },
}) })
} }
feedFromSession (data: Buffer): void { feedFromSession (data: Buffer): void {
const chunkSize = 1024 if (this.isActive || this.activeSession) {
for (let i = 0; i <= Math.floor(data.length / chunkSize); i++) {
try { try {
this.sentry.consume(Buffer.from(data.slice(i * chunkSize, (i + 1) * chunkSize))) this.sentry.consume(data)
} catch (e) { } catch (e) {
this.showMessage(colors.bgRed.black(' Error ') + ' ' + e) this.showMessage(colors.bgRed.black(' Error ') + ' ' + e)
this.logger.error('protocol error', e) this.logger.error('protocol error', e)
this.activeSession.abort() this.activeSession?.abort()
this.activeSession = null this.activeSession = null
this.isActive = false this.isActive = false
// Don't forward the problematic data to terminal
return return
} }
} } else {
if (!this.isActive) { try {
this.sentry.consume(data)
} catch (e) {
this.logger.error('zmodem detection error', e)
}
this.outputToTerminal.next(data) this.outputToTerminal.next(data)
} }
} }
@@ -73,25 +80,35 @@ class ZModemMiddleware extends SessionMiddleware {
this.activeSession = zsession this.activeSession = zsession
this.logger.info('new session', zsession) this.logger.info('new session', zsession)
if (zsession.type === 'send') { try {
const transfers = await this.platform.startUpload({ multiple: true }) if (zsession.type === 'send') {
let filesRemaining = transfers.length const transfers = await this.platform.startUpload({ multiple: true })
let sizeRemaining = transfers.reduce((a, b) => a + b.getSize(), 0) let filesRemaining = transfers.length
for (const transfer of transfers) { let sizeRemaining = transfers.reduce((a, b) => a + b.getSize(), 0)
await this.sendFile(zsession, transfer, filesRemaining, sizeRemaining) for (const transfer of transfers) {
filesRemaining-- await this.sendFile(zsession, transfer, filesRemaining, sizeRemaining)
sizeRemaining -= transfer.getSize() filesRemaining--
sizeRemaining -= transfer.getSize()
}
await zsession.close()
} else {
zsession.on('offer', xfer => {
this.receiveFile(xfer, zsession)
})
zsession.start()
await new Promise(resolve => zsession.on('session_end', resolve))
} }
this.activeSession = null
await zsession.close()
} else {
zsession.on('offer', xfer => {
this.receiveFile(xfer, zsession)
})
zsession.start() this.showMessage(colors.bgBlue.black(' ZMODEM ') + ' Complete')
} catch (error) {
await new Promise(resolve => zsession.on('session_end', resolve)) this.logger.error('ZMODEM session error', error)
this.showMessage(colors.bgRed.black(' ZMODEM ') + ` Session failed: ${error.message}`)
try {
zsession.abort()
} catch { }
} finally {
this.activeSession = null this.activeSession = null
} }
} }