diff --git a/src/contacts/Contact.cpp b/src/contacts/Contact.cpp index 084e7f72..e927b3e3 100644 --- a/src/contacts/Contact.cpp +++ b/src/contacts/Contact.cpp @@ -338,8 +338,8 @@ QDataStream &operator>>(QDataStream &in, Contact &contact) BlockInfo blockInfo; QList phoneNumbers; - in >> id >> dn >> sourceUid >> name >> prio >> displayName >> company >> mail >> lastModified - >> sipStatusSubscriptable >> phoneNumbers >> blockInfo; + in >> id >> dn >> sourceUid >> name >> prio >> displayName >> configId >> company >> mail + >> lastModified >> sipStatusSubscriptable >> phoneNumbers >> blockInfo; contact = Contact(id, dn, sourceUid, { prio, displayName, configId }, name, company, mail, lastModified, phoneNumbers, blockInfo); diff --git a/src/contacts/carddav/CardDAVAddressBookFeeder.cpp b/src/contacts/carddav/CardDAVAddressBookFeeder.cpp index 74635e92..dae8fa1d 100644 --- a/src/contacts/carddav/CardDAVAddressBookFeeder.cpp +++ b/src/contacts/carddav/CardDAVAddressBookFeeder.cpp @@ -219,18 +219,29 @@ void CardDAVAddressBookFeeder::loadCachedData(const size_t hash) QDataStream in(&cacheFile); - quint16 magic; - quint8 version; - qsizetype numberOfContacts; + quint16 magic = 0; + quint8 version = 0; in >> magic; in >> version; - in >> m_ignoredIds; - in >> numberOfContacts; - if (magic != CARDDAV_MAGIC || version != CARDDAV_VERSION) { + if (in.status() != QDataStream::Ok || magic != CARDDAV_MAGIC || version != CARDDAV_VERSION) { qCInfo(lcCardDAVAddressBookFeeder) << "CardDAV cache file at" << filePath << "is invalid and will therefore be removed."; + cacheFile.close(); + cacheFile.remove(); + return; + } + + qsizetype numberOfContacts = 0; + in >> m_ignoredIds; + in >> numberOfContacts; + + if (in.status() != QDataStream::Ok || numberOfContacts < 0 || numberOfContacts > 1000000) { + qCWarning(lcCardDAVAddressBookFeeder) << "CardDAV cache file at" << filePath + << "is corrupted and will therefore be removed."; + m_ignoredIds.clear(); + cacheFile.close(); cacheFile.remove(); return; } @@ -240,6 +251,20 @@ void CardDAVAddressBookFeeder::loadCachedData(const size_t hash) Contact *contact = new Contact(this); in >> key; in >> *contact; + + if (in.status() != QDataStream::Ok) { + delete contact; + qCWarning(lcCardDAVAddressBookFeeder) + << "CardDAV cache file at" << filePath + << "is truncated or corrupted - aborting cache load."; + qDeleteAll(m_cachedContacts); + m_cachedContacts.clear(); + m_ignoredIds.clear(); + cacheFile.close(); + cacheFile.remove(); + return; + } + m_cachedContacts.insert(key, contact); } diff --git a/src/media/AudioPort.cpp b/src/media/AudioPort.cpp index 1a713bbd..e3e0049f 100644 --- a/src/media/AudioPort.cpp +++ b/src/media/AudioPort.cpp @@ -35,7 +35,11 @@ bool AudioPort::initialize() createPort(m_device.id().toStdString(), m_pj_fmt); if (m_device.mode() == QAudioDevice::Mode::Input) { - adjustTxLevel(NORMAL_AUDIO_LEVEL); + try { + adjustTxLevel(NORMAL_AUDIO_LEVEL); + } catch (pj::Error &err) { + qCCritical(lcAudioPort) << "failed to adjust tx level: " << err.info(); + } } return true; @@ -45,7 +49,11 @@ void AudioPort::setMuted(bool value) { if (m_isMuted != value) { if (m_device.mode() == QAudioDevice::Mode::Input) { - adjustTxLevel(value ? 0.0f : NORMAL_AUDIO_LEVEL); + try { + adjustTxLevel(value ? 0.0f : NORMAL_AUDIO_LEVEL); + } catch (pj::Error &err) { + qCCritical(lcAudioPort) << "failed to adjust tx level: " << err.info(); + } } m_isMuted = value; @@ -166,8 +174,8 @@ void AudioPort::startSinkIO() qCInfo(lcAudioPort).noquote().nospace() << "Initialize sink of device_descr=\"" << m_device.description() << "\", device_id=\"" - << m_device.id() << "\", with settings:" - << "\nsampleRate=" << m_audioFormat.sampleRate() + << m_device.id() + << "\", with settings:" << "\nsampleRate=" << m_audioFormat.sampleRate() << "\nchannelCount=" << m_audioFormat.channelCount() << "\nbytesPerSample=" << m_audioFormat.bytesPerSample() << "\nsampleFormat=" << m_audioFormat.sampleFormat(); @@ -208,8 +216,8 @@ void AudioPort::startSourceIO() qCInfo(lcAudioPort).noquote().nospace() << "Initialize source of device_descr=\"" << m_device.description() - << "\", device_id=\"" << m_device.id() << "\", with settings:" - << "\nsampleRate=" << m_audioFormat.sampleRate() + << "\", device_id=\"" << m_device.id() + << "\", with settings:" << "\nsampleRate=" << m_audioFormat.sampleRate() << "\nchannelCount=" << m_audioFormat.channelCount() << "\nbytesPerSample=" << m_audioFormat.bytesPerSample() << "\nsampleFormat=" << m_audioFormat.sampleFormat(); diff --git a/src/sip/SIPCall.cpp b/src/sip/SIPCall.cpp index 8b30f53c..a4274e8e 100644 --- a/src/sip/SIPCall.cpp +++ b/src/sip/SIPCall.cpp @@ -20,6 +20,7 @@ #include "NotificationManager.h" #include "AvatarManager.h" #include "GlobalCallState.h" +#include "ErrorBus.h" #include #include @@ -159,8 +160,8 @@ void SIPCall::onCallState(pj::OnCallStateParam &prm) qCInfo(lcSIPCall).nospace() << "Call State: " << ci.stateText << " (" << remoteUri << ")" << " last status code: " << EnumTranslation::instance().sipStatusCode(statusCode) << " (" - << statusCode << ") " - << " last reason " << ci.lastReason << " contactId " << m_contactId; + << statusCode << ") " << " last reason " << ci.lastReason + << " contactId " << m_contactId; if (statusCode == PJSIP_SC_RINGING) { ringToneFactory.ringingTone()->start(); @@ -359,13 +360,35 @@ void SIPCall::onCallMediaState(pj::OnCallMediaStateParam &prm) qCInfo(lcSIPCall) << "Found media, index" << i << "of" << ci.media.size(); aud_med = getAudioMedia(i); - mic_media.startTransmit(aud_med); - aud_med.startTransmit(speaker_media); + + try { + mic_media.startTransmit(aud_med); + } catch (pj::Error &err) { + qCCritical(lcSIPCall) + << "failed to start mic media transmission: " << err.info(); + ErrorBus::instance().addFatalError( + tr("Failed to initialize microphone audio")); + } + + try { + aud_med.startTransmit(speaker_media); + } catch (pj::Error &err) { + qCCritical(lcSIPCall) + << "failed to start aud media transmission: " << err.info(); + ErrorBus::instance().addFatalError(tr("Failed to initialize call audio")); + } if (!m_sniffer) { m_sniffer = new Sniffer(this); m_sniffer->initialize(); - aud_med.startTransmit(dynamic_cast(*m_sniffer)); + + try { + aud_med.startTransmit(dynamic_cast(*m_sniffer)); + } catch (pj::Error &err) { + qCCritical(lcSIPCall) + << "failed to start audio level transmission: " << err.info(); + } + connect(m_sniffer, &Sniffer::audioLevelChanged, this, [this]() { Q_EMIT SIPCallManager::instance().audioLevelChanged( this, m_sniffer->audioLevel());