Skip to content

Commit 8d19295

Browse files
committed
Every picture on the site is uploadable from the panel
Fourteen places showed an image and only some of them could be changed without a deploy. Two separate causes. **SectionArt never asked the panel.** It looked in public/photos and nowhere else, so the six cards under "What we hire", the three "How it works" steps and the areas-we-serve panel all ignored anything uploaded. That is worse than having no slot: someone uploads a photograph of their own fleet, the panel says it saved, and the drawing stays. It asks useSiteImage now -- uploaded first, then a file in the repository, then the drawing -- which also makes the special case AreasServed carried for `coast` unnecessary. **Three more were hardcoded paths**: the home page background, the two photographs beside "Why hire from us", and the open road band. The first picture a visitor sees was the one picture the owner could not change. Website content gains thirteen slots: Home page background, the two Why-hire photos, Open road band, the six cards named after the page each links to, and the three steps. Nineteen images on the site, every one of them uploadable. Slot names may now contain digits. They could not: the sanitiser stripped them and the reader's pattern rejected them, so step-1, step-2 and step-3 would all have been written as "step-" and then served as a 404. The open road band stays a CSS background rather than becoming an <img>. If the file is missing the band falls back to the navy beneath it and still looks deliberate, where an <img> would leave a broken-image icon on a live page. Verified by seeding all thirteen new slots: every one renders, no drawing is left on the home page, the six cards carry their uploads on /services too, and nothing overflows at 390px. The seeds are not committed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0128YzbhrfGdegUSc9RrARRf
1 parent 25b2e66 commit 8d19295

25 files changed

Lines changed: 103 additions & 63 deletions

File tree

‎404.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
3838
rel="stylesheet"
3939
/>
40-
<script type="module" crossorigin src="/assets/index-CyFBp4oB.js"></script>
41-
<link rel="stylesheet" crossorigin href="/assets/index-DiSu9Gdq.css">
40+
<script type="module" crossorigin src="/assets/index-DpcbTMiT.js"></script>
41+
<link rel="stylesheet" crossorigin href="/assets/index-DYlnpUbm.css">
4242
</head>
4343
<body>
4444
<div id="root"></div>

‎about/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
3838
rel="stylesheet"
3939
/>
40-
<script type="module" crossorigin src="/assets/index-CyFBp4oB.js"></script>
41-
<link rel="stylesheet" crossorigin href="/assets/index-DiSu9Gdq.css">
40+
<script type="module" crossorigin src="/assets/index-DpcbTMiT.js"></script>
41+
<link rel="stylesheet" crossorigin href="/assets/index-DYlnpUbm.css">
4242
</head>
4343
<body>
4444
<div id="root"></div>

‎admin/brand.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
$name = (string) ($_GET['f'] ?? '');
1616

17-
if (!preg_match('/^b[a-z][a-z-]*-[0-9a-f]{16}\.(jpg|png|webp|avif)$/', $name, $m)) {
17+
if (!preg_match('/^b[a-z][a-z0-9-]*-[0-9a-f]{16}\.(jpg|png|webp|avif)$/', $name, $m)) {
1818
http_response_code(404);
1919
header('Content-Type: text/plain; charset=utf-8');
2020
exit("Not found\n");

‎admin/src/site-images.php‎

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,28 @@
3838
'places-hero' => 'Places to visit banner',
3939
'services-hero' => 'What we hire banner',
4040

41+
// The home page, top to bottom.
42+
'home-hero' => 'Home page background',
43+
'why-us-1' => 'Why hire from us — large photo',
44+
'why-us-2' => 'Why hire from us — small photo',
45+
'open-road' => 'Open road band',
46+
4147
// The panel on the home page listing the towns served.
4248
'coast' => 'Areas we serve panel',
49+
50+
// The six cards under "What we hire", on the home page and on /services.
51+
// Named after the page each one links to, which is what the site asks for.
52+
'cars' => 'Card: self drive cars',
53+
'bikes' => 'Card: bike rental',
54+
'wedding-cars' => 'Card: wedding cars',
55+
'tourist-vehicles' => 'Card: tourist vehicles',
56+
'monthly' => 'Card: monthly rental',
57+
'nri' => 'Card: for NRI visitors',
58+
59+
// The three "How it works" steps.
60+
'step-1' => 'How it works: step 1',
61+
'step-2' => 'How it works: step 2',
62+
'step-3' => 'How it works: step 3',
4363
];
4464

4565
function site_image_dir(): string
@@ -105,9 +125,11 @@ function site_image_save(string $slot, array $file, int $userId): ?string
105125
// Our name, never the uploader's: a filename from a browser can contain
106126
// path separators, and writing outside this directory is the one thing
107127
// that must not be possible.
108-
// Hyphens kept: stripping them turned cars-hero into carshero, which is
109-
// still unique but tells a reader nothing. brand.php's pattern allows them.
110-
$name = sprintf('b%s-%s.%s', preg_replace('/[^a-z-]/', '', $slot),
128+
// Hyphens and digits kept: stripping hyphens turned cars-hero into
129+
// carshero, and stripping digits turned step-1, step-2 and step-3 into
130+
// three files all called step-. Still unique, and it tells a reader
131+
// nothing. brand.php's pattern allows both.
132+
$name = sprintf('b%s-%s.%s', preg_replace('/[^a-z0-9-]/', '', $slot),
111133
bin2hex(random_bytes(8)), $extension);
112134

113135
if (!move_uploaded_file((string) $file['tmp_name'], site_image_dir() . '/' . $name)) {

‎assets/index-CyFBp4oB.js‎

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎assets/index-DYlnpUbm.css‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎assets/index-DiSu9Gdq.css‎

Lines changed: 0 additions & 2 deletions
This file was deleted.

‎assets/index-DpcbTMiT.js‎

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎bikes/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
3838
rel="stylesheet"
3939
/>
40-
<script type="module" crossorigin src="/assets/index-CyFBp4oB.js"></script>
41-
<link rel="stylesheet" crossorigin href="/assets/index-DiSu9Gdq.css">
40+
<script type="module" crossorigin src="/assets/index-DpcbTMiT.js"></script>
41+
<link rel="stylesheet" crossorigin href="/assets/index-DYlnpUbm.css">
4242
</head>
4343
<body>
4444
<div id="root"></div>

‎blog/index.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"
3838
rel="stylesheet"
3939
/>
40-
<script type="module" crossorigin src="/assets/index-CyFBp4oB.js"></script>
41-
<link rel="stylesheet" crossorigin href="/assets/index-DiSu9Gdq.css">
40+
<script type="module" crossorigin src="/assets/index-DpcbTMiT.js"></script>
41+
<link rel="stylesheet" crossorigin href="/assets/index-DYlnpUbm.css">
4242
</head>
4343
<body>
4444
<div id="root"></div>

0 commit comments

Comments
 (0)