Changeset 93918 in vbox
- Timestamp:
- Feb 24, 2022 1:58:10 PM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 150145
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/UnattendedScript.cpp
r93839 r93918 57 57 58 58 59 /********************************************************************************************************************************* 60 * Static Functions * 61 *********************************************************************************************************************************/ 62 63 /** 64 * Searches comparison operators'<', '<=', '>', '>=', or '=' in string. 65 * 66 * @returns true if detected, false if not. 67 * @param pszComparisonOperator Comparison operators string array. Assumed to be of size 3, 68 * @param pachPlaceholder The string array in which we search the comparison operators, 69 * @param startPos The position with in the pachPlaceholder from where the seach starts. Required to be smaller then 70 * sizeof(pachPlaceholder) - 3 71 */ 72 73 static bool detectComparisonOperator(char *pszComparisonOperator, const char *pachPlaceholder, size_t &startPos) 74 { 75 memset(pszComparisonOperator, '\0', 3); 76 /* Search for '>', '<', '>=', '<=', '='. */ 77 if (pachPlaceholder[startPos] == '<') 78 { 79 pszComparisonOperator[0] = '<'; 80 ++startPos; 81 if (pachPlaceholder[startPos] == '=') 82 { 83 pszComparisonOperator[1] = '='; 84 ++startPos; 85 } 86 return true; 87 } 88 if (pachPlaceholder[startPos] == '>') 89 { 90 pszComparisonOperator[0] = '>'; 91 ++startPos; 92 if (pachPlaceholder[startPos] == '=') 93 { 94 pszComparisonOperator[1] = '='; 95 ++startPos; 96 } 97 return true; 98 } 99 else if (pachPlaceholder[startPos] == '=') 100 { 101 pszComparisonOperator[0] = '='; 102 ++startPos; 103 return true; 104 } 105 return false; 106 } 59 107 /********************************************************************************************************************************* 60 108 * UnattendedScriptTemplate Implementation * … … 795 843 else if (IS_PLACEHOLDER_MATCH("HAS_PROXY")) 796 844 *pfOutputting = mpUnattended->i_getProxy().isNotEmpty(); 797 else if (IS_PLACEHOLDER_PARTIALLY_MATCH("GUEST_VERSION")) 798 { 799 //parse the placeholder and extract the OS version from there 800 RTCString strPlaceHolder(pachPlaceholder); /** @todo r=bird: What's the meaning of duplicating the rest of the script here 801 * when you could just add cchPlaceholder to the parameter list and limit it to 802 * what is actually needed. OTOH it's really not needed to make copies here, 803 * validating the "[" can be done in the partial match above and "]@@" by using 804 * cchPlaceholder, what you wnat to get at is inbetween and does not need 805 * two copies (only one for RTStrVersionCompare). */ 806 size_t startPos = sizeof("@@VBOX_COND_GUEST_VERSION") - 1;//-1 is for '\n' 807 size_t endPos = strPlaceHolder.find("@@", startPos + 2); 808 //next part should look like [>8.0.0] for example where: 809 // - "[,]" is just the brackets to wrap up the condition; 810 // - ">" is "greater". Also possible comparison is "<"; 811 // - 8.0.0 is required guest OS version. 812 //The end of placeholder is "@@" like for others. 813 814 /** @todo r=bird: What kind of syntax checking is this? Ignore any kind of 815 * mistyped stuff and let the user figure out what he did wrong 816 * without clues? Lazy. */ 817 if ( strPlaceHolder[endPos] == '@' 818 && strPlaceHolder[endPos+1] == '@' ) 819 { 820 if ( strPlaceHolder[startPos++] == '[' && strPlaceHolder[--endPos] == ']' ) 821 { 822 char chComp = strPlaceHolder[startPos++]; 823 RTCString strRequiredOSVersion = strPlaceHolder.substr(startPos, endPos - startPos); 824 RTCString strDetectedOSVersion = mpUnattended->i_getDetectedOSVersion(); 825 int res = RTStrVersionCompare(strDetectedOSVersion.c_str(), strRequiredOSVersion.c_str()); 826 if ( res >= 0 && chComp == '>' ) 827 *pfOutputting = true; 828 else if ( res < 0 && chComp == '<' ) 829 *pfOutputting = true; 830 else if ( res == 0 && chComp == '=' ) 831 *pfOutputting = true; 832 else 833 *pfOutputting = false; 834 } 835 } 845 else if (IS_PLACEHOLDER_PARTIALLY_MATCH("GUEST_VERSION[")) 846 { 847 /* Check the passed string against format @@VBOX_COND_GUEST_VERSION[>8.04.0]@@. Allowed comparison operators are: 848 * '<', '<=', '>', '>=', or '=' in string. No spaces are allowed in anywhere of the expr. */ 849 static const char s_szTail[] = "]@@"; 850 size_t endLength = sizeof(s_szTail) - 1; 851 if (memcmp(&pachPlaceholder[cchPlaceholder - endLength], RT_STR_TUPLE(s_szTail)) != 0) 852 { 853 *pfOutputting = false; 854 return mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, tr("Malformed @@VBOX_COND_GUEST_VERSION[expr]@@: Missing ']' (%.*s)"), 855 cchPlaceholder, pachPlaceholder); 856 } 857 size_t startPos = sizeof("@@VBOX_COND_GUEST_VERSION[") - 1; 858 size_t endPos = cchPlaceholder - endLength; 859 if (startPos >= endPos) 860 { 861 *pfOutputting = false; 862 return mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, tr("Malformed @@VBOX_COND_GUEST_VERSION[expr]@@: Missing expr (%.*s)"), 863 cchPlaceholder, pachPlaceholder); 864 } 865 /* Parse for the comparison operator. Assuming the expression starts with one of the allowed operators. */ 866 char pszComparisonOperator[3]; 867 if (!detectComparisonOperator(pszComparisonOperator, pachPlaceholder, startPos)) 868 { 869 *pfOutputting = false; 870 return mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, tr("Malformed @@VBOX_COND_GUEST_VERSION[expr]@@: Only space, '>', '>=', '<', <=', and '=' are allowed at the start. (%.*s)"), 871 cchPlaceholder, pachPlaceholder); 872 } 873 if (startPos >= endPos) 874 { 875 *pfOutputting = false; 876 return mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, tr("Malformed @@VBOX_COND_GUEST_VERSION[expr]@@: No version string found. (%.*s)"), 877 cchPlaceholder, pachPlaceholder); 878 } 879 /* Check if the version string includes any character other than '.' and digits. */ 880 for (size_t i = startPos; i < endPos; ++i) 881 { 882 if ( (pachPlaceholder[i] < '0' || pachPlaceholder[i] > '9') && pachPlaceholder[i] != '.') 883 { 884 *pfOutputting = false; 885 return mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, tr("Malformed @@VBOX_COND_GUEST_VERSION[expr]@@: Version string must be consist of only digits and '.', and no spaces. (%.*s)"), 886 cchPlaceholder, pachPlaceholder); 887 } 888 } 889 890 RTCString strRequiredOSVersion(pachPlaceholder, startPos, endPos - startPos); 891 RTCString strDetectedOSVersion = mpUnattended->i_getDetectedOSVersion(); 892 int res = RTStrVersionCompare(strDetectedOSVersion.c_str(), strRequiredOSVersion.c_str()); 893 894 if ( res == 0 895 && ( pszComparisonOperator[0] == '=' 896 || memcmp(pszComparisonOperator, ">=", 2) == 0 897 || memcmp(pszComparisonOperator, "<=", 2) == 0)) 898 *pfOutputting = true; 899 else if (res < 0 && pszComparisonOperator[0] == '<') 900 *pfOutputting = true; 901 else if (res > 0 && pszComparisonOperator[0] == '>') 902 *pfOutputting = true; 836 903 else 837 *pfOutputting = false; //initially is set to "false"904 *pfOutputting = false; 838 905 } 839 906 else … … 988 1055 } 989 1056 #endif /* just for reference */ 990
Note:
See TracChangeset
for help on using the changeset viewer.