From c85ecce1e717795fa909357ad5d22a83341f3424 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 6 Sep 2017 05:47:11 -0400 Subject: [PATCH] YAML-NetInstall: log data errors. When NetInstall receives YAML data, handle parser errors more gracefully: show line and column, but because it's network data (not in a local file), do some work to print out the actual data received. FIXES #786 --- src/modules/netinstall/NetInstallPage.cpp | 67 ++++++++++++++++++++--- src/modules/netinstall/NetInstallPage.h | 3 +- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index b5fa702d6..fe5b600ab 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -64,14 +64,59 @@ NetInstallPage::isReady() return true; } -void NetInstallPage::readGroups( const QByteArray& yamlData ) +bool +NetInstallPage::readGroups( const QByteArray& yamlData ) { - YAML::Node groups = YAML::Load( yamlData.constData() ); - Q_ASSERT( groups.IsSequence() ); - m_groups = new PackageModel( groups ); - CALAMARES_RETRANSLATE( - m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); - m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Description" ) ); ) + try + { + YAML::Node groups = YAML::Load( yamlData.constData() ); + + if ( !groups.IsSequence() ) + cDebug() << "WARNING: netinstall groups data does not form a sequence."; + Q_ASSERT( groups.IsSequence() ); + m_groups = new PackageModel( groups ); + CALAMARES_RETRANSLATE( + m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Name" ) ); + m_groups->setHeaderData( 0, Qt::Horizontal, tr( "Description" ) ); ) + return true; + + } + catch ( YAML::Exception& e ) + { + cDebug() << "WARNING: YAML error " << e.what() << "in netinstall groups data."; + if ( ( e.mark.line >= 0 ) && ( e.mark.column >= 0 ) ) + { + // Try to show the line where it happened. + int linestart = 0; + for ( int linecount = 0; linecount < e.mark.line; ++linecount ) + { + linestart = yamlData.indexOf( '\n', linestart ); + // No more \ns found, weird + if ( linestart < 0 ) + break; + linestart += 1; // Skip that \n + } + int lineend = linestart; + if ( linestart >= 0 ) + { + lineend = yamlData.indexOf( '\n', linestart ); + if ( lineend < 0 ) + lineend = yamlData.length(); + } + + int rangestart = linestart; + int rangeend = lineend; + // Adjust range (linestart..lineend) so it's not too long + if ( ( linestart >= 0 ) && ( e.mark.column > 30 ) ) + rangestart += ( e.mark.column - 30 ); + if ( ( linestart >= 0 ) && ( rangeend - rangestart > 40 ) ) + rangeend = rangestart + 40; + + if ( linestart >= 0 ) + cDebug() << "WARNING: offending YAML data:" << yamlData.mid( rangestart, rangeend-rangestart ).constData(); + } + return false; + } } void @@ -84,7 +129,13 @@ NetInstallPage::dataIsHere( QNetworkReply* reply ) return; } - readGroups( reply->readAll() ); + if ( !readGroups( reply->readAll() ) ) + { + cDebug() << "Netinstall groups data was received, but invalid."; + ui->netinst_status->setText( tr( "Network Installation. (Disabled: Unable to fetch package lists, check your network connection)" ) ); + reply->deleteLater(); + return; + } ui->groupswidget->setModel( m_groups ); ui->groupswidget->header()->setSectionResizeMode( 0, QHeaderView::ResizeToContents ); diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 7ecc74f89..423c16b8e 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -2,6 +2,7 @@ * Copyright 2016, Luca Giambonini * Copyright 2016, Lisa Vitolo * Copyright 2017, Kyle Robbertze + * Copyright 2017, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -67,7 +68,7 @@ private: // Takes the YAML data representing the groups and reads them into the // m_groups and m_groupOrder internal structures. See the README.md // of this module to know the format expected of the YAML files. - void readGroups( const QByteArray& yamlData ); + bool readGroups( const QByteArray& yamlData ); Ui::Page_NetInst* ui;