clang format

This commit is contained in:
Brendan O'Leary 2025-12-16 21:42:36 -05:00
parent e9e6982eea
commit 05da79f6ad
9 changed files with 192 additions and 198 deletions

View File

@ -2,6 +2,7 @@
#include <SD.h>
#include <WiFi.h>
#include <algorithm>
#include "config.h"
@ -11,10 +12,7 @@ CrossPointWebServer crossPointWebServer;
// Folders/files to hide from the web interface file browser
// Note: Items starting with "." are automatically hidden
static const char* HIDDEN_ITEMS[] = {
"System Volume Information",
"XTCache"
};
static const char* HIDDEN_ITEMS[] = {"System Volume Information", "XTCache"};
static const size_t HIDDEN_ITEMS_COUNT = sizeof(HIDDEN_ITEMS) / sizeof(HIDDEN_ITEMS[0]);
// Helper function to escape HTML special characters to prevent XSS
@ -25,12 +23,24 @@ static String escapeHtml(const String& input) {
for (size_t i = 0; i < input.length(); i++) {
char c = input.charAt(i);
switch (c) {
case '&': output += "&amp;"; break;
case '<': output += "&lt;"; break;
case '>': output += "&gt;"; break;
case '"': output += "&quot;"; break;
case '\'': output += "&#39;"; break;
default: output += c; break;
case '&':
output += "&amp;";
break;
case '<':
output += "&lt;";
break;
case '>':
output += "&gt;";
break;
case '"':
output += "&quot;";
break;
case '\'':
output += "&#39;";
break;
default:
output += c;
break;
}
}
return output;
@ -849,9 +859,7 @@ static const char* FILES_PAGE_FOOTER = R"rawliteral(
CrossPointWebServer::CrossPointWebServer() {}
CrossPointWebServer::~CrossPointWebServer() {
stop();
}
CrossPointWebServer::~CrossPointWebServer() { stop(); }
void CrossPointWebServer::begin() {
if (running) {
@ -1176,7 +1184,8 @@ void CrossPointWebServer::handleFileList() {
html += "<tr class=\"" + rowClass + "\">";
html += "<td><span class=\"file-icon\">" + icon + "</span>";
html += "<a href=\"/files?path=" + folderPath + "\" class=\"folder-link\">" + escapeHtml(file.name) + "</a>" + badge + "</td>";
html += "<a href=\"/files?path=" + folderPath + "\" class=\"folder-link\">" + escapeHtml(file.name) + "</a>" +
badge + "</td>";
html += "<td>" + typeStr + "</td>";
html += "<td>" + sizeStr + "</td>";
// Escape quotes for JavaScript string
@ -1184,7 +1193,8 @@ void CrossPointWebServer::handleFileList() {
escapedName.replace("'", "\\'");
String escapedPath = folderPath;
escapedPath.replace("'", "\\'");
html += "<td class=\"actions-col\"><button class=\"delete-btn\" onclick=\"openDeleteModal('" + escapedName + "', '" + escapedPath + "', true)\" title=\"Delete folder\">🗑️</button></td>";
html += "<td class=\"actions-col\"><button class=\"delete-btn\" onclick=\"openDeleteModal('" + escapedName +
"', '" + escapedPath + "', true)\" title=\"Delete folder\">🗑️</button></td>";
html += "</tr>";
} else {
rowClass = file.isEpub ? "epub-file" : "";
@ -1209,7 +1219,8 @@ void CrossPointWebServer::handleFileList() {
escapedName.replace("'", "\\'");
String escapedPath = filePath;
escapedPath.replace("'", "\\'");
html += "<td class=\"actions-col\"><button class=\"delete-btn\" onclick=\"openDeleteModal('" + escapedName + "', '" + escapedPath + "', false)\" title=\"Delete file\">🗑️</button></td>";
html += "<td class=\"actions-col\"><button class=\"delete-btn\" onclick=\"openDeleteModal('" + escapedName +
"', '" + escapedPath + "', false)\" title=\"Delete file\">🗑️</button></td>";
html += "</tr>";
}
}
@ -1288,8 +1299,7 @@ void CrossPointWebServer::handleUpload() {
}
Serial.printf("[%lu] [WEB] File created: %s\n", millis(), filePath.c_str());
}
else if (upload.status == UPLOAD_FILE_WRITE) {
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (uploadFile && uploadError.isEmpty()) {
size_t written = uploadFile.write(upload.buf, upload.currentSize);
if (written != upload.currentSize) {
@ -1300,8 +1310,7 @@ void CrossPointWebServer::handleUpload() {
uploadSize += written;
}
}
}
else if (upload.status == UPLOAD_FILE_END) {
} else if (upload.status == UPLOAD_FILE_END) {
if (uploadFile) {
uploadFile.close();
@ -1310,8 +1319,7 @@ void CrossPointWebServer::handleUpload() {
Serial.printf("[%lu] [WEB] Upload complete: %s (%d bytes)\n", millis(), uploadFileName.c_str(), uploadSize);
}
}
}
else if (upload.status == UPLOAD_FILE_ABORTED) {
} else if (upload.status == UPLOAD_FILE_ABORTED) {
if (uploadFile) {
uploadFile.close();
// Try to delete the incomplete file

View File

@ -1,6 +1,7 @@
#pragma once
#include <WebServer.h>
#include <functional>
#include <string>
#include <vector>

View File

@ -17,8 +17,7 @@ constexpr char WIFI_FILE[] = "/sd/.crosspoint/wifi.bin";
// Obfuscation key - "CrossPoint" in ASCII
// This is NOT cryptographic security, just prevents casual file reading
constexpr uint8_t OBFUSCATION_KEY[] = {0x43, 0x72, 0x6F, 0x73, 0x73,
0x50, 0x6F, 0x69, 0x6E, 0x74};
constexpr uint8_t OBFUSCATION_KEY[] = {0x43, 0x72, 0x6F, 0x73, 0x73, 0x50, 0x6F, 0x69, 0x6E, 0x74};
constexpr size_t KEY_LENGTH = sizeof(OBFUSCATION_KEY);
void WifiCredentialStore::obfuscate(std::string& data) const {
@ -46,7 +45,8 @@ bool WifiCredentialStore::saveToFile() const {
for (const auto& cred : credentials) {
// Write SSID (plaintext - not sensitive)
serialization::writeString(file, cred.ssid);
Serial.printf("[%lu] [WCS] Saving SSID: %s, password length: %zu\n", millis(), cred.ssid.c_str(), cred.password.size());
Serial.printf("[%lu] [WCS] Saving SSID: %s, password length: %zu\n", millis(), cred.ssid.c_str(),
cred.password.size());
// Write password (obfuscated)
std::string obfuscatedPwd = cred.password;
@ -94,7 +94,8 @@ bool WifiCredentialStore::loadFromFile() {
// Read and deobfuscate password
serialization::readString(file, cred.password);
Serial.printf("[%lu] [WCS] Loaded SSID: %s, obfuscated password length: %zu\n", millis(), cred.ssid.c_str(), cred.password.size());
Serial.printf("[%lu] [WCS] Loaded SSID: %s, obfuscated password length: %zu\n", millis(), cred.ssid.c_str(),
cred.password.size());
obfuscate(cred.password); // XOR is symmetric, so same function deobfuscates
Serial.printf("[%lu] [WCS] After deobfuscation, password length: %zu\n", millis(), cred.password.size());
@ -148,9 +149,7 @@ const WifiCredential* WifiCredentialStore::findCredential(const std::string& ssi
return nullptr;
}
bool WifiCredentialStore::hasSavedCredential(const std::string& ssid) const {
return findCredential(ssid) != nullptr;
}
bool WifiCredentialStore::hasSavedCredential(const std::string& ssid) const { return findCredential(ssid) != nullptr; }
void WifiCredentialStore::clearAll() {
credentials.clear();

View File

@ -4,25 +4,16 @@
// Keyboard layouts - lowercase
const char* const OnScreenKeyboard::keyboard[NUM_ROWS] = {
"`1234567890-=",
"qwertyuiop[]\\",
"asdfghjkl;'",
"zxcvbnm,./",
"`1234567890-=", "qwertyuiop[]\\", "asdfghjkl;'", "zxcvbnm,./",
"^ _____<OK" // ^ = shift, _ = space, < = backspace, OK = done
};
// Keyboard layouts - uppercase/symbols
const char* const OnScreenKeyboard::keyboardShift[NUM_ROWS] = {
"~!@#$%^&*()_+",
"QWERTYUIOP{}|",
"ASDFGHJKL:\"",
"ZXCVBNM<>?",
"^ _____<OK"
};
const char* const OnScreenKeyboard::keyboardShift[NUM_ROWS] = {"~!@#$%^&*()_+", "QWERTYUIOP{}|", "ASDFGHJKL:\"",
"ZXCVBNM<>?", "^ _____<OK"};
OnScreenKeyboard::OnScreenKeyboard(GfxRenderer& renderer, InputManager& inputManager,
const std::string& title, const std::string& initialText,
size_t maxLength, bool isPassword)
OnScreenKeyboard::OnScreenKeyboard(GfxRenderer& renderer, InputManager& inputManager, const std::string& title,
const std::string& initialText, size_t maxLength, bool isPassword)
: renderer(renderer),
inputManager(inputManager),
title(title),
@ -54,12 +45,18 @@ int OnScreenKeyboard::getRowLength(int row) const {
// Return actual length of each row based on keyboard layout
switch (row) {
case 0: return 13; // `1234567890-=
case 1: return 13; // qwertyuiop[]backslash
case 2: return 11; // asdfghjkl;'
case 3: return 10; // zxcvbnm,./
case 4: return 10; // ^, space (5 wide), backspace, OK (2 wide)
default: return 0;
case 0:
return 13; // `1234567890-=
case 1:
return 13; // qwertyuiop[]backslash
case 2:
return 11; // asdfghjkl;'
case 3:
return 10; // zxcvbnm,./
case 4:
return 10; // ^, space (5 wide), backspace, OK (2 wide)
default:
return 0;
}
}

View File

@ -31,11 +31,8 @@ class OnScreenKeyboard {
* @param maxLength Maximum length of input text (0 for unlimited)
* @param isPassword If true, display asterisks instead of actual characters
*/
OnScreenKeyboard(GfxRenderer& renderer, InputManager& inputManager,
const std::string& title = "Enter Text",
const std::string& initialText = "",
size_t maxLength = 0,
bool isPassword = false);
OnScreenKeyboard(GfxRenderer& renderer, InputManager& inputManager, const std::string& title = "Enter Text",
const std::string& initialText = "", size_t maxLength = 0, bool isPassword = false);
/**
* Handle button input. Call this in your screen's handleInput().

View File

@ -41,8 +41,7 @@ class SettingsScreen final : public Screen {
void activateCurrentSetting();
public:
explicit SettingsScreen(GfxRenderer& renderer, InputManager& inputManager,
const std::function<void()>& onGoHome,
explicit SettingsScreen(GfxRenderer& renderer, InputManager& inputManager, const std::function<void()>& onGoHome,
const std::function<void()>& onGoWifi)
: Screen(renderer, inputManager), onGoHome(onGoHome), onGoWifi(onGoWifi) {}
void onEnter() override;

View File

@ -136,7 +136,8 @@ void WifiScreen::selectNetwork(int index) {
// Use saved password - connect directly
enteredPassword = savedCred->password;
usedSavedPassword = true;
Serial.printf("[%lu] [WiFi] Using saved password for %s, length: %zu\n", millis(), selectedSSID.c_str(), enteredPassword.size());
Serial.printf("[%lu] [WiFi] Using saved password for %s, length: %zu\n", millis(), selectedSSID.c_str(),
enteredPassword.size());
attemptConnection();
return;
}
@ -144,9 +145,7 @@ void WifiScreen::selectNetwork(int index) {
if (selectedRequiresPassword) {
// Show password entry
state = WifiScreenState::PASSWORD_ENTRY;
keyboard.reset(new OnScreenKeyboard(
renderer, inputManager,
"Enter WiFi Password",
keyboard.reset(new OnScreenKeyboard(renderer, inputManager, "Enter WiFi Password",
"", // No initial text
64, // Max password length
false // Show password by default (hard keyboard to use)
@ -263,14 +262,12 @@ void WifiScreen::handleInput() {
// Handle save prompt state
if (state == WifiScreenState::SAVE_PROMPT) {
if (inputManager.wasPressed(InputManager::BTN_LEFT) ||
inputManager.wasPressed(InputManager::BTN_UP)) {
if (inputManager.wasPressed(InputManager::BTN_LEFT) || inputManager.wasPressed(InputManager::BTN_UP)) {
if (savePromptSelection > 0) {
savePromptSelection--;
updateRequired = true;
}
} else if (inputManager.wasPressed(InputManager::BTN_RIGHT) ||
inputManager.wasPressed(InputManager::BTN_DOWN)) {
} else if (inputManager.wasPressed(InputManager::BTN_RIGHT) || inputManager.wasPressed(InputManager::BTN_DOWN)) {
if (savePromptSelection < 1) {
savePromptSelection++;
updateRequired = true;
@ -293,14 +290,12 @@ void WifiScreen::handleInput() {
// Handle forget prompt state (connection failed with saved credentials)
if (state == WifiScreenState::FORGET_PROMPT) {
if (inputManager.wasPressed(InputManager::BTN_LEFT) ||
inputManager.wasPressed(InputManager::BTN_UP)) {
if (inputManager.wasPressed(InputManager::BTN_LEFT) || inputManager.wasPressed(InputManager::BTN_UP)) {
if (forgetPromptSelection > 0) {
forgetPromptSelection--;
updateRequired = true;
}
} else if (inputManager.wasPressed(InputManager::BTN_RIGHT) ||
inputManager.wasPressed(InputManager::BTN_DOWN)) {
} else if (inputManager.wasPressed(InputManager::BTN_RIGHT) || inputManager.wasPressed(InputManager::BTN_DOWN)) {
if (forgetPromptSelection < 1) {
forgetPromptSelection++;
updateRequired = true;
@ -330,8 +325,7 @@ void WifiScreen::handleInput() {
// Handle connected state
if (state == WifiScreenState::CONNECTED) {
if (inputManager.wasPressed(InputManager::BTN_BACK) ||
inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
if (inputManager.wasPressed(InputManager::BTN_BACK) || inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
// Exit screen on success
onGoBack();
return;
@ -340,8 +334,7 @@ void WifiScreen::handleInput() {
// Handle connection failed state
if (state == WifiScreenState::CONNECTION_FAILED) {
if (inputManager.wasPressed(InputManager::BTN_BACK) ||
inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
if (inputManager.wasPressed(InputManager::BTN_BACK) || inputManager.wasPressed(InputManager::BTN_CONFIRM)) {
// If we used saved credentials, offer to forget the network
if (usedSavedPassword) {
state = WifiScreenState::FORGET_PROMPT;