| 12159 | |
| 12160 | |
| 12161 | ResultType Script::DerefInclude(LPTSTR &aOutput, LPTSTR aBuf) |
| 12162 | // For #Include, #IncludeAgain and #DllLoad. |
| 12163 | // Based on Line::Deref above, but with a few differences for backward-compatibility: |
| 12164 | // 1) Percent signs that aren't part of a valid deref are not omitted. |
| 12165 | // 2) Escape sequences aren't recognized (`; is handled elsewhere). |
| 12166 | // 3) It is restricted to built-in vars to reduce the risk of breaking any scripts |
| 12167 | // that use percent sign literally in a filename. Most other vars are empty anyway. |
| 12168 | { |
| 12169 | aOutput = nullptr; // Set default. |
| 12170 | |
| 12171 | VarSizeType expanded_length; |
| 12172 | size_t var_name_length; |
| 12173 | LPTSTR cp, cp1, dest; |
| 12174 | |
| 12175 | // Do two passes: |
| 12176 | // #1: Calculate the space needed. |
| 12177 | // #2: Expand the contents of aBuf into aOutput. |
| 12178 | |
| 12179 | for (int which_pass = 0; which_pass < 2; ++which_pass) |
| 12180 | { |
| 12181 | if (which_pass) // Starting second pass. |
| 12182 | { |
| 12183 | // Allocate a buffer to contain the result: |
| 12184 | if ( !(aOutput = tmalloc(expanded_length+1)) ) |
| 12185 | return FAIL; |
| 12186 | dest = aOutput; |
| 12187 | } |
| 12188 | else // First pass. |
| 12189 | expanded_length = 0; // Init prior to accumulation. |
| 12190 | |
| 12191 | for (cp = aBuf; *cp; ++cp) // Increment to skip over the deref/escape just found by the inner for(). |
| 12192 | { |
| 12193 | if (*cp == g_DerefChar) |
| 12194 | { |
| 12195 | // It's a dereference symbol, so calculate the size of that variable's contents and add |
| 12196 | // that to expanded_length (or copy the contents into aOutputVar if this is the second pass). |
| 12197 | for (cp1 = cp + 1; *cp1 && *cp1 != g_DerefChar; ++cp1); // Find the reference's ending symbol. |
| 12198 | var_name_length = cp1 - cp - 1; |
| 12199 | if (*cp1 && var_name_length && var_name_length <= MAX_VAR_NAME_LENGTH) |
| 12200 | { |
| 12201 | Var *var = FindGlobalVar(cp + 1, var_name_length); |
| 12202 | if (var && var->Type() == VAR_VIRTUAL) |
| 12203 | { |
| 12204 | if (which_pass) // 2nd pass |
| 12205 | { |
| 12206 | size_t var_length = var->CharLength(); |
| 12207 | tmemcpy(dest, var->Contents(), var_length); |
| 12208 | var->Free(); |
| 12209 | dest += var_length; |
| 12210 | } |
| 12211 | else |
| 12212 | { |
| 12213 | if (!var->PopulateVirtualVar()) |
| 12214 | return FAIL; |
| 12215 | expanded_length += var->CharLength(); |
| 12216 | } |
| 12217 | cp = cp1; // For the next loop iteration, continue at the char after this reference's final deref symbol. |
| 12218 | continue; |
nothing calls this directly
no test coverage detected