Ejemplo n.º 1
0
// FIXME: need to be checked
bool InputProtocolBase::safeReadBytes( QCString & data, uint & len )
{
	// read the length of the bytes
	Q_UINT32 val;
	if ( !okToProceed() )
		return false;
	*m_din >> val;
	m_bytes += sizeof( Q_UINT32 );
	if ( val > 1024 )
		return false;
	//qDebug( "EventProtocol::safeReadBytes() - expecting %i bytes", val );
	QCString temp( val );
	if ( val != 0 )
	{
		if ( !okToProceed() )
			return false;
		// if the server splits packets here we are in trouble,
		// as there is no way to see how much data was actually read
		m_din->readRawBytes( temp.data(), val );
		// the rest of the string will be filled with FF,
		// so look for that in the last position instead of \0
		// this caused a crash - guessing that temp.length() is set to the number of bytes actually read...
		// if ( (quint8)( * ( temp.data() + ( temp.length() - 1 ) ) ) == 0xFF )
		if ( temp.length() < static_cast<int>( val - 1 ) )
		{
			qDebug( "InputProtocol::safeReadBytes() - string broke, giving up, only got: %i bytes out of %i",  temp.length(), val );
			m_state = NeedMore;
			return false;
		}
	}
	data = temp;
	len = val;
	m_bytes += val;
	return true;
}
Ejemplo n.º 2
0
bool ResponseProtocol::readFields( int fieldCount, Field::FieldList * list )
{
	// build a list of fields.  
	// If there is already a list of fields stored in m_collatingFields, 
	// the list we're reading on this iteration must be a nested list
	// so when we're done reading it, add it to the MultiList element
	// that is the last element in the top list in m_collatingFields.
	// if we find the beginning of a new nested list, push the current list onto m_collatingFields
	debug( "ResponseProtocol::readFields()" );
	if ( fieldCount > 0 )
		debug( QString( "reading %1 fields" ).arg( fieldCount ) );
	Field::FieldList currentList;
	while ( fieldCount != 0 )  // prevents bad input data from ruining our day
	{
		// the field being read
		// read field
		Q_UINT8 type, method;
		Q_UINT32 val;
		QCString tag;
		// read uint8 type
		if ( !okToProceed() )
		{
			currentList.purge();
			return false;
		}
		m_din >> type;
		m_bytes += sizeof( Q_UINT8 );
		// if type is 0 SOMETHING_INVALID, we're at the end of the fields
		if ( type == 0 ) /*&& m_din->atEnd() )*/
		{
			debug( "- end of field list" );
			m_packetState = FieldsRead;
			// do something to indicate we're done
			break;
		}
		// read uint8 method
		if ( !okToProceed() )
		{
			currentList.purge();
			return false;
		}
		m_din >> method;
		m_bytes += sizeof( Q_UINT8 );
		// read tag and length
		if ( !safeReadBytes( tag, val ) )
		{
			currentList.purge();
			return false;
		}

		debug( QString( "- type: %1, method: %2, tag: %3," ).arg( type ).arg( method ).arg( tag.data() ) );
		// if multivalue or array
		if ( type == NMFIELD_TYPE_MV || type == NMFIELD_TYPE_ARRAY )
		{
			// read length uint32
			if ( !okToProceed() )
			{
				currentList.purge();
				return false;
			}
			m_din >> val;
			m_bytes += sizeof( Q_UINT32 );

			// create multifield
			debug( QString( " multi field containing: %1" ).arg( val ) );
			Field::MultiField* m = new Field::MultiField( tag, method, 0, type );
			currentList.append( m );
			if ( !readFields( val, &currentList) )
			{
				currentList.purge();
				return false;
			}
		}
		else 
		{
		
			if ( type == NMFIELD_TYPE_UTF8 || type == NMFIELD_TYPE_DN )
			{
				QCString rawData;
				if( !safeReadBytes( rawData, val ) )
				{
					currentList.purge();
					return false;
				}
				if ( val > NMFIELD_MAX_STR_LENGTH )
				{
					m_packetState = ProtocolError;
					break;
				}
				// convert to unicode - ignore the terminating NUL, because Qt<3.3.2 doesn't sanity check val.
				QString fieldValue = QString::fromUtf8( rawData.data(), val - 1 );
				debug( QString( "- utf/dn single field: %1" ).arg( fieldValue ) );
				// create singlefield
				Field::SingleField* s = new Field::SingleField( tag, method, 0, type, fieldValue );
				currentList.append( s );
			}
			else
			{
				// otherwise ( numeric )
				// read value uint32
				if ( !okToProceed() )
				{
					currentList.purge();
					return false;
				}
				m_din >> val;
				m_bytes += sizeof( Q_UINT32 );
				debug( QString( "- numeric field: %1" ).arg( val ) );
				Field::SingleField* s = new Field::SingleField( tag, method, 0, type, val );
				currentList.append( s );
			}
		}
		// decrease the fieldCount if we're using it
		if ( fieldCount > 0 )
			fieldCount--;
	}
Ejemplo n.º 3
0
int CoreProtocol::wireToTransfer( const QByteArray& wire )
{
	kDebug(YAHOO_RAW_DEBUG) ;
	// processing incoming data and reassembling it into transfers
	// may be an event or a response
	
	uint bytesParsed = 0;
			
	if ( wire.size() < 20 ) // minimal value of a YMSG header
	{
		m_state = NeedMore;
		return bytesParsed;
	}
	
	QByteArray tempWire = wire;
	QDataStream din( &tempWire, QIODevice::ReadOnly );
	
	// look at first four bytes and decide what to do with the chunk
	if ( okToProceed( din ) )
	{
		if ( (wire[0] == 'Y') && (wire[1] == 'M') && (wire[2] == 'S') && (wire[3] == 'G'))
		{
// 			kDebug(YAHOO_RAW_DEBUG) << " - looks like a valid YMSG packet";
			YMSGTransfer *t = static_cast<YMSGTransfer *>(m_YMSGProtocol->parse( wire, bytesParsed ));
// 			kDebug(YAHOO_RAW_DEBUG) << " - YMSG Protocol parsed " << bytesParsed << " bytes";
			if ( t )
			{
				if( wire.size() < t->packetLength() )
				{
					m_state = NeedMore;
					delete t;
					return 0;
				}
				m_inTransfer = t;
// 				kDebug(YAHOO_RAW_DEBUG) << " - got a valid packet ";
				
				m_state = Available;
				emit incomingData();
			}
			else
				bytesParsed = 0;
		}
		else 
		{ 
			kDebug(YAHOO_RAW_DEBUG) << " - not a valid YMSG packet. Trying to recover.";
			QTextStream s( wire, QIODevice::ReadOnly );
			QString remaining = s.readAll();
			int pos = remaining.indexOf( "YMSG", bytesParsed );
			if( pos >= 0 )
			{
				kDebug(YAHOO_RAW_DEBUG) << "Recover successful.";
				bytesParsed += pos;
			}
			else
			{
				kDebug(YAHOO_RAW_DEBUG) << "Recover failed. Dump it!";
				bytesParsed = wire.size();
			}
		}
	}
	return bytesParsed;
}