@@ -123,11 +123,6 @@ void ScrollSorter_T<COMP>::SetupRefMatch()
123123 const ISphSchema * pSchema = m_pSorter->GetSchema ();
124124 assert (pSchema);
125125
126- // Safety check: if scroll settings are invalid, don't set up reference match
127- // This check must come BEFORE FreeDataPtrAttrs() to prevent accessing corrupted data
128- if ( !m_tScroll.m_dAttrs .GetLength () )
129- return ;
130-
131126 // Free old data pointer attributes before resetting
132127 FreeDataPtrAttrs ();
133128
@@ -163,9 +158,13 @@ void ScrollSorter_T<COMP>::SetupRefMatch()
163158 switch ( i.m_eType )
164159 {
165160 case SPH_ATTR_STRINGPTR:
166- sphSetRowAttr ( pRowData, pAttr->m_tLocator , (SphAttr_t)sphPackPtrAttr ( { (const BYTE*)i.m_sValue .cstr (), i.m_sValue .Length () } ) );
167- // Track that we allocated a pointer for this attribute
168- m_dAllocatedPtrAttrs.Add (pAttr);
161+ // After remapping, pAttr should be SPH_ATTR_STRINGPTR, but check to be safe
162+ if ( pAttr->m_eAttrType ==SPH_ATTR_STRINGPTR )
163+ {
164+ sphSetRowAttr ( pRowData, pAttr->m_tLocator , (SphAttr_t)sphPackPtrAttr ( { (const BYTE*)i.m_sValue .cstr (), i.m_sValue .Length () } ) );
165+ // Track that we allocated a pointer for this attribute
166+ m_dAllocatedPtrAttrs.Add (pAttr);
167+ }
169168 break ;
170169
171170 case SPH_ATTR_FLOAT:
@@ -402,6 +401,10 @@ bool SetupScroll ( CSphQuery & tQuery, CSphString & sError )
402401 if ( !tQuery.m_tScrollSettings .m_dAttrs .GetLength () )
403402 return true ;
404403
404+ // Ensure m_sSortBy is set (scroll settings are valid)
405+ if ( tQuery.m_tScrollSettings .m_sSortBy .IsEmpty () )
406+ return true ;
407+
405408 // replace order by with order_by_str here (if order by is default)
406409 const char * szDefaultSortBy = " @weight desc" ;
407410 if ( tQuery.m_sSortBy ==szDefaultSortBy )
0 commit comments