Skip to content

Commit 160aeb1

Browse files
pxpmtabacitu
andauthored
Parse basset arguments (#152)
* correctly parset basset arguments * correctly parse the basset arguments * Apply fixes from StyleCI --------- Co-authored-by: tabacitu <tabacitu@users.noreply.github.com>
1 parent 7a6438b commit 160aeb1

File tree

2 files changed

+93
-16
lines changed

2 files changed

+93
-16
lines changed

src/BassetManager.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,19 @@ public function loadAsset(CacheEntry $asset, $output)
221221
return $this->loader->finish(StatusEnum::IN_CACHE);
222222
}
223223

224+
if (str_starts_with($asset->getAssetPath(), public_path())) {
225+
$output && $this->output->write($asset);
226+
227+
return $this->loader->finish(StatusEnum::PUBLIC_FILE);
228+
}
229+
224230
// Download/copy file
225231
$content = $this->getAssetContent($asset, $output);
226232

227233
if (! is_string($content)) {
228234
return $content;
229235
}
230236

231-
if (str_starts_with($asset->getAssetPath(), public_path())) {
232-
$output && $this->output->write($asset);
233-
234-
return $this->loader->finish(StatusEnum::PUBLIC_FILE);
235-
}
236-
237237
return $this->uploadAssetToDisk($asset, $content, $output);
238238
}
239239

src/Console/Commands/BassetCache.php

Lines changed: 87 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,11 @@ public function handle(): void
7070
preg_match_all('/(basset|@bassetArchive|@bassetDirectory)\((.+)\)/', $content, $matches);
7171

7272
$matches[2] = collect($matches[2])
73-
->map(fn ($match) => collect(explode(',', $match))
74-
->map(function ($arg) {
75-
try {
76-
return eval("return $arg;");
77-
} catch (Throwable $th) {
78-
return false;
79-
}
80-
})
81-
->toArray()
82-
);
73+
->map(fn ($match) => $this->parseBassetArguments($match));
8374

8475
return collect($matches[1])->map(fn (string $type, int $i) => [$type, $matches[2][$i]]);
8576
});
77+
8678
$totalBassets = count($bassets);
8779
if (! $totalBassets) {
8880
$this->line('No bassets found.');
@@ -165,6 +157,91 @@ public function handle(): void
165157
$this->info(sprintf('Done in %.2fs', microtime(true) - $starttime));
166158
}
167159

160+
/**
161+
* Parse basset arguments from a string, respecting array boundaries and quotes.
162+
*
163+
* @param string $argumentString
164+
* @return array
165+
*/
166+
private function parseBassetArguments(string $argumentString): array
167+
{
168+
$length = strlen($argumentString);
169+
$arguments = [];
170+
$current = '';
171+
$state = [
172+
'inQuotes' => false,
173+
'quoteChar' => null,
174+
'bracketDepth' => 0,
175+
'parenDepth' => 0,
176+
];
177+
178+
for ($i = 0; $i < $length; $i++) {
179+
$char = $argumentString[$i];
180+
$isEscaped = $i > 0 && $argumentString[$i - 1] === '\\';
181+
182+
if (in_array($char, ['"', "'"], true) && ! $isEscaped) {
183+
if (! $state['inQuotes']) {
184+
$state['inQuotes'] = true;
185+
$state['quoteChar'] = $char;
186+
} elseif ($char === $state['quoteChar']) {
187+
$state['inQuotes'] = false;
188+
$state['quoteChar'] = null;
189+
}
190+
$current .= $char;
191+
continue;
192+
}
193+
194+
if ($state['inQuotes']) {
195+
$current .= $char;
196+
continue;
197+
}
198+
199+
$state['bracketDepth'] += match ($char) {
200+
'[' => 1,
201+
']' => -1,
202+
default => 0,
203+
};
204+
205+
$state['parenDepth'] += match ($char) {
206+
'(' => 1,
207+
')' => -1,
208+
default => 0,
209+
};
210+
211+
if ($char === ',' && $state['bracketDepth'] === 0 && $state['parenDepth'] === 0) {
212+
$arguments[] = $this->evaluateArgument(trim($current));
213+
$current = '';
214+
} else {
215+
$current .= $char;
216+
}
217+
}
218+
219+
if (($finalArg = trim($current)) !== '') {
220+
$arguments[] = $this->evaluateArgument($finalArg);
221+
}
222+
223+
return $arguments;
224+
}
225+
226+
/**
227+
* Safely evaluate a single argument string.
228+
*
229+
* @param string $argument
230+
* @return mixed
231+
*/
232+
private function evaluateArgument(string $argument): mixed
233+
{
234+
if ($argument === '') {
235+
return false;
236+
}
237+
238+
try {
239+
return eval("return $argument;");
240+
} catch (Throwable) {
241+
return false;
242+
}
243+
}
244+
168245
/**
169246
* Gets all blade files in a directory recursively.
170247
*

0 commit comments

Comments
 (0)