@@ -34,14 +34,15 @@ static bool parseData(
3434	QTreeWidgetItem* parent,
3535	const  void * ptr,
3636	unsigned  int  len,
37+ 	bool  ignorePadding,
3738	bool  decode,
38- 	unsigned  int * validBytes 
39+ 	unsigned  int * totalValidBytes 
3940)
4041{
4142	int  r;
43+ 	unsigned  int  validBytes = 0 ;
4244	struct  iso8825_ber_itr_t  itr;
4345	struct  iso8825_tlv_t  tlv;
44- 	bool  valid;
4546
4647	r = iso8825_ber_itr_init (ptr, len, &itr);
4748	if  (r) {
@@ -50,10 +51,12 @@ static bool parseData(
5051	}
5152
5253	while  ((r = iso8825_ber_itr_next (&itr, &tlv)) > 0 ) {
54+ 		unsigned  int  fieldLength = r;
55+ 
5356		EmvTreeItem* item = new  EmvTreeItem (
5457			parent,
55- 			*validBytes ,
56- 			r ,
58+ 			*totalValidBytes ,
59+ 			fieldLength ,
5760			&tlv,
5861			decode
5962		);
@@ -62,32 +65,72 @@ static bool parseData(
6265			//  If the field is constructed, only consider the tag and length
6366			//  to be valid until the value has been parsed. The fields inside
6467			//  the value will be added when they are parsed.
65- 			*validBytes += (r - tlv.length );
68+ 			validBytes += (r - tlv.length );
69+ 			*totalValidBytes += (r - tlv.length );
6670
6771			//  Recursively parse constructed fields
68- 			valid = parseData (item, tlv.value , tlv.length , decode, validBytes);
72+ 			bool  valid;
73+ 			valid = parseData (
74+ 				item,
75+ 				tlv.value ,
76+ 				tlv.length ,
77+ 				ignorePadding,
78+ 				decode,
79+ 				totalValidBytes
80+ 			);
6981			if  (!valid) {
70- 				qDebug (" parseBerData() failed; validBytes=%u"  , *validBytes);
82+ 				qDebug (" parseData() failed; totalValidBytes=%u"  , *totalValidBytes);
83+ 
84+ 				//  Return here instead of breaking out to avoid repeated
85+ 				//  processing of the error by recursive callers
7186				return  false ;
7287			}
88+ 			validBytes += tlv.length ;
7389
7490		} else  {
7591			//  If the field is not constructed, consider all of the bytes to
7692			//  be valid BER encoded data
77- 			*validBytes += r;
93+ 			validBytes += r;
94+ 			*totalValidBytes += r;
7895		}
7996	}
8097	if  (r < 0 ) {
81- 		qDebug (" iso8825_ber_itr_next() failed; r=%d"  , r);
82- 		return  false ;
98+ 		//  Determine whether invalid data is padding and prepare item details
99+ 		//  accordingly
100+ 		if  (ignorePadding &&
101+ 			len - validBytes > 0  &&
102+ 			(
103+ 				((len & 0x7 ) == 0  && len - validBytes < 8 ) ||
104+ 				((len & 0xF ) == 0  && len - validBytes < 16 )
105+ 			)
106+ 		) {
107+ 			//  Invalid data is likely to be padding
108+ 			EmvTreeItem* item = new  EmvTreeItem (
109+ 				parent,
110+ 				*totalValidBytes,
111+ 				len - validBytes,
112+ 				" Padding"  ,
113+ 				reinterpret_cast <const  char *>(ptr) + validBytes
114+ 			);
115+ 			item->setForeground (0 , Qt::darkGray);
116+ 
117+ 			//  If the remaining bytes appear to be padding, consider these
118+ 			//  bytes to be valid
119+ 			*totalValidBytes += len - validBytes;
120+ 			validBytes = len;
121+ 
122+ 		} else  {
123+ 			qDebug (" iso8825_ber_itr_next() failed; r=%d"  , r);
124+ 			return  false ;
125+ 		}
83126	}
84127
85128	return  true ;
86129}
87130
88131unsigned  int  EmvTreeView::populateItems (const  QByteArray& data)
89132{
90- 	unsigned  int  validBytes  = 0 ;
133+ 	unsigned  int  totalValidBytes  = 0 ;
91134
92135	//  For now, clear the widget before repopulating it. In future, the widget
93136	//  should be updated incrementally instead.
@@ -97,15 +140,22 @@ unsigned int EmvTreeView::populateItems(const QByteArray& data)
97140		invisibleRootItem (),
98141		data.constData(),
99142		data.size(),
143+ 		m_ignorePadding,
100144		m_decodeFields,
101- 		&validBytes 
145+ 		&totalValidBytes 
102146	);
103147
104- 	return  validBytes ;
148+ 	return  totalValidBytes ;
105149}
106150
107151void  EmvTreeView::setDecodeFields (bool  enabled)
108152{
153+ 	if  (m_decodeFields == enabled) {
154+ 		//  No change
155+ 		return ;
156+ 	}
157+ 	m_decodeFields = enabled;
158+ 
109159	//  Visit all EMV children recursively and re-render them according to the
110160	//  current state
111161	QTreeWidgetItemIterator itr  (this );
@@ -117,6 +167,4 @@ void EmvTreeView::setDecodeFields(bool enabled)
117167		}
118168		++itr;
119169	}
120- 
121- 	m_decodeFields = enabled;
122170}
0 commit comments