Refactor GetStrArraySeparatedByChar, replaced by Split

This commit is contained in:
jief666 2020-08-13 11:21:45 +03:00
parent 59d8cbad7f
commit 052732eba0
3 changed files with 62 additions and 227 deletions

View File

@ -1368,151 +1368,34 @@ FillinKextPatches (IN OUT KERNEL_AND_KEXT_PATCHES *Patches,
BOOLEAN
IsPatchEnabled (const XString8& MatchOSEntry, const XString8& CurrOS)
{
INTN i;
BOOLEAN ret = FALSE;
struct MatchOSes *mos; // = (__typeof__(mos))AllocatePool(sizeof(struct MatchOSes));
if (MatchOSEntry.isEmpty() || CurrOS.isEmpty()) {
return TRUE; //undefined matched corresponds to old behavior
}
mos = GetStrArraySeparatedByChar(MatchOSEntry.c_str(), ',');
if (!mos) {
return TRUE; //memory fails -> anyway the patch enabled
}
XString8Array mos = Split<XString8Array>(MatchOSEntry, ","_XS8).trimEachString();
TrimMatchOSArray(mos);
if (AsciiStrStr(mos->array[0], "All") != NULL) {
if ( mos[0] == "All"_XS8) {
return TRUE;
}
for (i = 0; i < mos->count; ++i) {
for (size_t i = 0; i < mos.size(); ++i) {
// dot represent MatchOS
if (
((AsciiStrStr(mos->array[i], ".") != NULL) && IsOSValid(mos->array[i], CurrOS.c_str())) || // MatchOS
(AsciiStrStr(mos->array[i], CurrOS.c_str()) != NULL) // MatchBuild
( mos[i].contains("."_XS8) && IsOSValid(mos[i], CurrOS)) || // MatchOS
( mos[i].contains(CurrOS) ) // MatchBuild
) {
//DBG("\nthis patch will activated for OS %ls!\n", mos->array[i]);
ret = TRUE;
break;
}
}
deallocMatchOSes(mos);
return ret;
}
struct
MatchOSes *GetStrArraySeparatedByChar(const CHAR8 *str, CHAR8 sep)
{
struct MatchOSes *mo;
INTN len = 0, i = 0, inc = 1, newLen = 0;
// CHAR8 *comp = NULL; //unused
CHAR8 doubleSep[2];
mo = (__typeof__(mo))AllocatePool(sizeof(struct MatchOSes));
if (!mo) {
return NULL;
}
mo->count = countOccurrences( str, sep ) + 1;
// DBG("found %d %c in %ls\n", mo->count, sep, str);
len = (INTN)AsciiStrLen(str);
doubleSep[0] = sep; doubleSep[1] = sep;
if(AsciiStrStr(str, doubleSep) || !len || str[0] == sep || str[len -1] == sep) {
mo->count = 0;
mo->array[0] = NULL;
// DBG("emtpy string\n");
return mo;
}
if (mo->count > 1) {
//INTN indexes[mo->count + 1];
INTN *indexes = (INTN *) AllocatePool(mo->count + 1);
for (i = 0; i < len; ++i) {
CHAR8 c = str[i];
if (c == sep) {
indexes[inc]=i;
// DBG("index %d = %d\n", inc, i);
inc++;
}
}
// manually add first index
indexes[0] = 0;
// manually add last index
indexes[mo->count] = len;
for (i = 0; i < mo->count; ++i) {
INTN startLocation, endLocation;
mo->array[i] = 0;
if (i == 0) {
startLocation = indexes[0];
endLocation = indexes[1] - 1;
} else if (i == mo->count - 1) { // never reach the end of the array
startLocation = indexes[i] + 1;
endLocation = len;
} else {
startLocation = indexes[i] + 1;
endLocation = indexes[i + 1] - 1;
}
// DBG("start %d, end %d\n", startLocation, endLocation);
newLen = (endLocation - startLocation) + 2;
/* comp = (CHAR8 *) AllocatePool(newLen);
AsciiStrnCpy(comp, str + startLocation, newLen);
comp[newLen] = '\0'; */
mo->array[i] = (__typeof_am__(mo->array[i]))AllocateCopyPool(newLen, str + startLocation);
mo->array[i][newLen - 1] = '\0';
}
FreePool(indexes);
}
else {
// DBG("str contains only one component and it is our string %ls!\n", str);
mo->array[0] = (__typeof_am__(mo->array[0]))AllocateCopyPool(AsciiStrLen(str)+1, str);
}
return mo;
}
CHAR8*
TrimString(CHAR8* String)
{
CHAR8 *TempString, *End, *TrimmedString;
if (!String) {
return NULL;
}
TempString = String;
for ( ; *TempString == ' '; TempString++) {
}
End = TempString + AsciiStrLen(TempString) - 1;
for ( ; (End > TempString) && (*End == ' '); End--) {
}
*(End + 1) = '\0';
TrimmedString = (__typeof__(TrimmedString))AllocateCopyPool(AsciiStrSize(TempString), TempString);
FreePool(String);
return TrimmedString;
}
VOID
TrimMatchOSArray(struct MatchOSes *s)
{
INTN i;
if (!s) {
return;
}
for (i = 0; i < s->count; i++) {
s->array[i] = TrimString(s->array[i]);
}
}
BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS)
BOOLEAN IsOSValid(const XString8& MatchOS, const XString8& CurrOS)
{
/* example for valid matches are:
10.7, only 10.7 (10.7.1 will be skipped)
@ -1521,76 +1404,46 @@ BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS)
*/
BOOLEAN ret = FALSE;
struct MatchOSes *osToc;
struct MatchOSes *currOStoc;
if (!MatchOS || !CurrOS) {
if (MatchOS.isEmpty() || CurrOS.isEmpty()) {
return TRUE; //undefined matched corresponds to old behavior
}
osToc = GetStrArraySeparatedByChar(MatchOS, '.');
currOStoc = GetStrArraySeparatedByChar(CurrOS, '.');
// osToc = GetStrArraySeparatedByChar(MatchOS, '.');
XString8Array osToc = Split<XString8Array>(MatchOS, "."_XS8).trimEachString();
XString8Array currOStoc = Split<XString8Array>(CurrOS, "."_XS8).trimEachString();
if (osToc->count == 2) {
if (currOStoc->count == 2) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0) {
if (osToc.size() == 2) {
if (currOStoc.size() == 2) {
if ( osToc[0] == currOStoc[0] && osToc[1] == currOStoc[1]) {
ret = TRUE;
}
}
} else if (osToc->count == 3) {
if (currOStoc->count == 3) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0
&& AsciiStrCmp(osToc->array[2], currOStoc->array[2]) == 0) {
} else if (osToc.size() == 3) {
if (currOStoc.size() == 3) {
if ( osToc[0] == currOStoc[0]
&& osToc[1] == currOStoc[1]
&& osToc[2] == currOStoc[2]) {
ret = TRUE;
} else if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0
&& (AsciiStrCmp(osToc->array[2], "x") == 0 || AsciiStrCmp(osToc->array[2], "X") == 0)) {
} else if ( osToc[0] == currOStoc[0]
&& osToc[1] == currOStoc[1]
&& osToc[2].equalIC("x") ) {
ret = TRUE;
}
} else if (currOStoc->count == 2) {
if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0) {
} else if (currOStoc.size() == 2) {
if ( osToc[0] == currOStoc[0]
&& osToc[1] == currOStoc[1] ) {
ret = TRUE;
} else if (AsciiStrCmp(osToc->array[0], currOStoc->array[0]) == 0
&& AsciiStrCmp(osToc->array[1], currOStoc->array[1]) == 0
&& (AsciiStrCmp(osToc->array[2], "x") == 0 || AsciiStrCmp(osToc->array[2], "X") == 0)) {
} else if ( osToc[0] == currOStoc[0]
&& osToc[1] == currOStoc[1]
&& osToc[2].equalIC("x") == 0 ) {
ret = TRUE;
}
}
}
deallocMatchOSes(osToc);
deallocMatchOSes(currOStoc);
return ret;
}
INTN countOccurrences( const CHAR8 *s, CHAR8 c )
{
return *s == '\0'
? 0
: countOccurrences( s + 1, c ) + (*s == c);
}
VOID deallocMatchOSes(struct MatchOSes *s)
{
INTN i;
if (!s) {
return;
}
for (i = 0; i < s->count; i++) {
if (s->array[i]) {
FreePool(s->array[i]);
}
}
FreePool(s);
}
// End of MatchOS
UINT8 CheckVolumeType(UINT8 VolumeType, TagPtr Prop)
{
UINT8 VolumeTypeTmp = VolumeType;

View File

@ -922,30 +922,7 @@ BOOLEAN IsPatchEnabled(const XString8& MatchOSEntry, const XString8& CurrOS);
/** return true if a given os contains '.' as separator,
and then match components of the current booted OS. Also allow 10.10.x format meaning all revisions
of the 10.10 OS */
BOOLEAN IsOSValid(const CHAR8 *MatchOS, const CHAR8 *CurrOS);
// Micky1979: Next five functions (+ needed struct) are to split a string like "10.10.5,10.7,10.11.6,10.8.x"
// in their components separated by comma (in this case)
struct MatchOSes {
INTN count;
CHAR8* array[100];
};
/** return MatchOSes struct (count+array) with the components of str that contains the given char sep as separator. */
struct
MatchOSes *GetStrArraySeparatedByChar(const CHAR8 *str, CHAR8 sep);
/** trim spaces in MatchOSes struct array */
VOID
TrimMatchOSArray(struct MatchOSes *s);
/** free MatchOSes struct and its array. */
VOID deallocMatchOSes(struct MatchOSes *s);
/** count occurrences of a given char in a char* string. */
INTN
countOccurrences(const CHAR8 *s, CHAR8 c);
BOOLEAN IsOSValid(const XString8& MatchOS, const XString8& CurrOS);
//get default boot

View File

@ -19,46 +19,42 @@
template<typename T, typename Tdummy=void>
struct _xstringarray__char_type;
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
// typedef const char* type;
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
template<typename T>
struct _xstringarray__char_type<T*, enable_if_t(is_char(T))>
{
typedef const T* type;
static const T* getCharPtr(T* t) { return t; }
};
//
//template<typename T>
//struct _xstringarray__char_type<const T*, enable_if_t(is_char(T))>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
//
//template<typename T>
//struct _xstringarray__char_type<const T[]>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
//
//template<typename T, size_t _Np>
//struct _xstringarray__char_type<const T[_Np]>
//{
// typedef const T* type;
// static const T* getCharPtr(const T* t) { return t; }
//};
template<typename T>
struct _xstringarray__char_type<T, enable_if_t(is___String(T))>
{
typedef const char* type;
static const typename T::char_t* getCharPtr(const T& t) { return t.s(); }
};
//#define XStringArraySuper XObjArray<XStringClass>
#define XStringArraySuper XObjArray<XStringClass>
template<class XStringClass_>
template<class XStringClass_, class XStringArrayClass>
class XStringArray_/* : public XStringArraySuper*/
{
protected:
@ -78,6 +74,8 @@ class XStringArray_/* : public XStringArraySuper*/
/* [] */
template<typename IntegralType, enable_if(is_integral(IntegralType))>
const XStringClass& operator [](IntegralType i) const { return array[i]; }
template<typename IntegralType, enable_if(is_integral(IntegralType))>
XStringClass& operator [](IntegralType i) { return array[i]; }
/* ElementAt */
template<typename IntegralType, enable_if(is_integral(IntegralType))>
const XStringClass& elementAt(IntegralType i) const { return array[i]; }
@ -204,14 +202,14 @@ class XStringArray_/* : public XStringArraySuper*/
{
XStringClass* newS = new XStringClass;
newS->takeValueFrom(Val1);
XStringArraySuper::AddReference(newS, true);
AddReference(newS, true);
}
va_start(va, Val1);
p = VA_ARG(va, const CharType*);
while ( p != nullptr ) {
XStringClass* newS = new XStringClass;
newS->takeValueFrom(Val1);
XStringArraySuper::AddReference(newS, true);
AddReference(newS, true);
p = VA_ARG(va, const CharType*);
}
va_end(va);
@ -228,13 +226,13 @@ class XStringArray_/* : public XStringArraySuper*/
array.AddReference(xstr, true);
}
// void Add(const XStringClass &aString) { array.AddCopy(aString); }
template<typename XStringClass1, enable_if(is___String(XStringClass1))>
void Add(const XStringClass1 &aString) { Add(aString.s()); }
void AddReference(XStringClass *newElement, bool FreeIt) { array.AddReference(newElement, FreeIt); }
template<class OtherXStringClass>
void import(const XStringArray_<OtherXStringClass> &aStrings)
template<class OtherXStringClass, class OtherXStringArrayClass>
void import(const XStringArray_<OtherXStringClass, OtherXStringArrayClass> &aStrings)
{
size_t i;
@ -283,25 +281,32 @@ class XStringArray_/* : public XStringArraySuper*/
} while ( i > 0 );
}
}
XStringArrayClass trimEachString()
{
for ( size_t i=0 ; i<array.size() ; i+=1 ) {
array.ElementAt(i).trim();
}
return *((XStringArrayClass*)this);
}
};
class XString8Array : public XStringArray_<XString8>
class XString8Array : public XStringArray_<XString8, XString8Array>
{
};
extern const XString8Array NullXString8Array;
class XString16Array : public XStringArray_<XString16>
class XString16Array : public XStringArray_<XString16, XString16Array>
{
};
extern const XString16Array NullXString16Array;
class XString32Array : public XStringArray_<XString32>
class XString32Array : public XStringArray_<XString32, XString32Array>
{
};
extern const XString32Array NullXString32Array;
class XStringWArray : public XStringArray_<XStringW>
class XStringWArray : public XStringArray_<XStringW, XStringWArray>
{
};
extern const XStringWArray NullXStringWArray;
@ -320,8 +325,8 @@ extern const XStringWArray NullXStringWArray;
//template<class XStringArrayClass, typename CharType1, typename CharType2, enable_if(is_char(CharType1) && is_char(CharType2))>
template<class XStringArrayClass, typename Type1, typename Type2,
enable_if(
( is_char_ptr(Type1) || is___String(Type1) ) &&
( is_char_ptr(Type2) || is___String(Type2) )
( is_char_ptr(Type1) || is___String(Type1) || is___LString(Type1) ) &&
( is_char_ptr(Type2) || is___String(Type2) || is___LString(Type2) )
)
>
XStringArrayClass Split(Type1 S, const Type2 Separator)