mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 17:17:09 -04:00
Avoid calling strlen with BearSSL
This commit is contained in:
parent
7bb3943467
commit
a3e54ebcf3
@ -1,131 +1,36 @@
|
||||
#include "Core.h"
|
||||
#ifndef CC_BUILD_WEB
|
||||
|
||||
#if defined CC_BUILD_WEB
|
||||
/* Implemented in web http backend without C worker thread(s) */
|
||||
#elif !defined CC_BUILD_NETWORKING
|
||||
#include "Http.h"
|
||||
#include "Game.h"
|
||||
|
||||
void HttpRequest_Free(struct HttpRequest* request) { }
|
||||
|
||||
cc_bool Http_GetResult(int reqID, struct HttpRequest* item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int Http_AsyncGetSkin(const cc_string* skinName, cc_uint8 flags) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Http_CheckProgress(int reqID) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Http_LogError(const char* action, const struct HttpRequest* item) {
|
||||
}
|
||||
|
||||
static void Http_NullInit(void) { }
|
||||
|
||||
struct IGameComponent Http_Component = {
|
||||
Http_NullInit
|
||||
};
|
||||
#else
|
||||
#include "_HttpBase.h"
|
||||
|
||||
/* Ensures data buffer has enough space left to append amount bytes */
|
||||
static cc_bool Http_BufferExpand(struct HttpRequest* req, cc_uint32 amount) {
|
||||
cc_uint32 newSize = req->size + amount;
|
||||
cc_uint8* ptr;
|
||||
if (newSize <= req->_capacity) return true;
|
||||
|
||||
if (!req->_capacity) {
|
||||
/* Allocate initial storage */
|
||||
req->_capacity = req->contentLength ? req->contentLength : 1;
|
||||
req->_capacity = max(req->_capacity, newSize);
|
||||
|
||||
ptr = (cc_uint8*)Mem_TryAlloc(req->_capacity, 1);
|
||||
} else {
|
||||
/* Reallocate if capacity reached */
|
||||
req->_capacity = newSize;
|
||||
ptr = (cc_uint8*)Mem_TryRealloc(req->data, newSize, 1);
|
||||
}
|
||||
|
||||
if (!ptr) return false;
|
||||
req->data = ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increases size and updates current progress */
|
||||
static void Http_BufferExpanded(struct HttpRequest* req, cc_uint32 read) {
|
||||
req->size += read;
|
||||
if (req->contentLength) req->progress = (int)(100.0f * req->size / req->contentLength);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------Common backend code---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) {
|
||||
cc_string name, data;
|
||||
int dataEnd;
|
||||
String_UNSAFE_Separate(value, '=', &name, &data);
|
||||
/* Cookie is: __cfduid=xyz; expires=abc; path=/; domain=.classicube.net; HttpOnly */
|
||||
/* However only the __cfduid=xyz part of the cookie should be stored */
|
||||
dataEnd = String_IndexOf(&data, ';');
|
||||
if (dataEnd >= 0) data.length = dataEnd;
|
||||
|
||||
EntryList_Set(req->cookies, &name, &data, '=');
|
||||
}
|
||||
|
||||
static void Http_ParseContentLength(struct HttpRequest* req, const cc_string* value) {
|
||||
int contentLen = 0;
|
||||
Convert_ParseInt(value, &contentLen);
|
||||
|
||||
if (contentLen <= 0) return;
|
||||
req->contentLength = contentLen;
|
||||
}
|
||||
|
||||
/* Parses a HTTP header */
|
||||
static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
||||
static const cc_string httpVersion = String_FromConst("HTTP");
|
||||
cc_string name, value, parts[3];
|
||||
int numParts;
|
||||
|
||||
/* HTTP[version] [status code] [status reason] */
|
||||
if (String_CaselessStarts(line, &httpVersion)) {
|
||||
numParts = String_UNSAFE_Split(line, ' ', parts, 3);
|
||||
if (numParts >= 2) Convert_ParseInt(&parts[1], &req->statusCode);
|
||||
}
|
||||
/* For all other headers: name: value */
|
||||
if (!String_UNSAFE_Separate(line, ':', &name, &value)) return;
|
||||
|
||||
if (String_CaselessEqualsConst(&name, "ETag")) {
|
||||
String_CopyToRawArray(req->etag, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) {
|
||||
/* dropbox stopped returning Content-Length header since switching to chunked transfer */
|
||||
/* https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Dropbox-media-can-t-be-access-by-azure-blob/td-p/575458 */
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
||||
String_CopyToRawArray(req->lastModified, &value);
|
||||
} else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) {
|
||||
Http_ParseCookie(req, &value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds a http header to the request headers. */
|
||||
static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value);
|
||||
|
||||
/* Adds all the appropriate headers for a request. */
|
||||
static void Http_SetRequestHeaders(struct HttpRequest* req) {
|
||||
static const cc_string contentType = String_FromConst("application/x-www-form-urlencoded");
|
||||
cc_string str, cookies; char cookiesBuffer[1024];
|
||||
int i;
|
||||
|
||||
if (req->lastModified[0]) {
|
||||
str = String_FromRawArray(req->lastModified);
|
||||
Http_AddHeader(req, "If-Modified-Since", &str);
|
||||
}
|
||||
if (req->etag[0]) {
|
||||
str = String_FromRawArray(req->etag);
|
||||
Http_AddHeader(req, "If-None-Match", &str);
|
||||
}
|
||||
|
||||
if (req->data) Http_AddHeader(req, "Content-Type", &contentType);
|
||||
if (!req->cookies || !req->cookies->count) return;
|
||||
|
||||
String_InitArray(cookies, cookiesBuffer);
|
||||
for (i = 0; i < req->cookies->count; i++) {
|
||||
if (i) String_AppendConst(&cookies, "; ");
|
||||
str = StringsBuffer_UNSAFE_Get(req->cookies, i);
|
||||
String_AppendString(&cookies, &str);
|
||||
}
|
||||
Http_AddHeader(req, "Cookie", &cookies);
|
||||
}
|
||||
|
||||
/* TODO: Rewrite to use a local variable instead */
|
||||
static cc_string* Http_GetUserAgent_UNSAFE(void) {
|
||||
static char userAgentBuffer[STRING_SIZE];
|
||||
static cc_string userAgent;
|
||||
|
||||
String_InitArray(userAgent, userAgentBuffer);
|
||||
String_AppendConst(&userAgent, GAME_APP_NAME);
|
||||
String_AppendConst(&userAgent, Platform_AppNameSuffix);
|
||||
return &userAgent;
|
||||
}
|
||||
|
||||
|
||||
#if CC_NET_BACKEND == CC_NET_BACKEND_BUILTIN
|
||||
#include "Errors.h"
|
||||
#include "PackedCol.h"
|
||||
@ -737,24 +642,6 @@ static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* urlStr) {
|
||||
static cc_bool HttpBackend_DescribeError(cc_result res, cc_string* dst) {
|
||||
return SSLBackend_DescribeError(res, dst);
|
||||
}
|
||||
#elif !defined CC_BUILD_NETWORKING
|
||||
/*########################################################################################################################*
|
||||
*------------------------------------------------------Null backend-------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#include "Errors.h"
|
||||
|
||||
static cc_bool HttpBackend_DescribeError(cc_result res, cc_string* dst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static void HttpBackend_Init(void) { }
|
||||
|
||||
static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value) { }
|
||||
|
||||
static cc_result HttpBackend_Do(struct HttpRequest* req, cc_string* url) {
|
||||
req->progress = 100;
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -578,6 +578,7 @@ static cc_result ExtractFrom(struct Stream* stream, const cc_string* path) {
|
||||
}
|
||||
|
||||
#if defined CC_BUILD_PS1 || defined CC_BUILD_SATURN
|
||||
/* Load hardcoded texture pack */
|
||||
#include "../misc/ps1/classicubezip.h"
|
||||
|
||||
static cc_result ExtractFromFile(const cc_string* path) {
|
||||
@ -586,6 +587,11 @@ static cc_result ExtractFromFile(const cc_string* path) {
|
||||
|
||||
return ExtractFrom(&stream, path);
|
||||
}
|
||||
#elif !defined CC_BUILD_FILESYSTEM
|
||||
/* E.g. GBA/32X don't support textures at all */
|
||||
static cc_result ExtractFromFile(const cc_string* path) {
|
||||
return ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#else
|
||||
static cc_result ExtractFromFile(const cc_string* path) {
|
||||
struct Stream stream;
|
||||
|
134
src/_HttpBase.h
134
src/_HttpBase.h
@ -23,14 +23,11 @@ void HttpRequest_Free(struct HttpRequest* request) {
|
||||
}
|
||||
#define HttpRequest_Copy(dst, src) Mem_Copy(dst, src, sizeof(struct HttpRequest))
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*----------------------------------------------------Http requests list---------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
#ifdef CC_BUILD_NETWORKING
|
||||
#define HTTP_DEF_ELEMS 10
|
||||
#else
|
||||
#define HTTP_DEF_ELEMS 1 /* TODO better unused code removal */
|
||||
#endif
|
||||
#define HTTP_DEF_ELEMS 10
|
||||
|
||||
struct RequestList {
|
||||
int count, capacity;
|
||||
@ -111,6 +108,133 @@ static void RequestList_Free(struct RequestList* list) {
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------Common buffer code----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
/* Ensures data buffer has enough space left to append amount bytes */
|
||||
static cc_bool Http_BufferExpand(struct HttpRequest* req, cc_uint32 amount) {
|
||||
cc_uint32 newSize = req->size + amount;
|
||||
cc_uint8* ptr;
|
||||
if (newSize <= req->_capacity) return true;
|
||||
|
||||
if (!req->_capacity) {
|
||||
/* Allocate initial storage */
|
||||
req->_capacity = req->contentLength ? req->contentLength : 1;
|
||||
req->_capacity = max(req->_capacity, newSize);
|
||||
|
||||
ptr = (cc_uint8*)Mem_TryAlloc(req->_capacity, 1);
|
||||
} else {
|
||||
/* Reallocate if capacity reached */
|
||||
req->_capacity = newSize;
|
||||
ptr = (cc_uint8*)Mem_TryRealloc(req->data, newSize, 1);
|
||||
}
|
||||
|
||||
if (!ptr) return false;
|
||||
req->data = ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increases size and updates current progress */
|
||||
static void Http_BufferExpanded(struct HttpRequest* req, cc_uint32 read) {
|
||||
req->size += read;
|
||||
if (req->contentLength) req->progress = (int)(100.0f * req->size / req->contentLength);
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------Common header code----------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
static void Http_ParseCookie(struct HttpRequest* req, const cc_string* value) {
|
||||
cc_string name, data;
|
||||
int dataEnd;
|
||||
String_UNSAFE_Separate(value, '=', &name, &data);
|
||||
/* Cookie is: __cfduid=xyz; expires=abc; path=/; domain=.classicube.net; HttpOnly */
|
||||
/* However only the __cfduid=xyz part of the cookie should be stored */
|
||||
dataEnd = String_IndexOf(&data, ';');
|
||||
if (dataEnd >= 0) data.length = dataEnd;
|
||||
|
||||
EntryList_Set(req->cookies, &name, &data, '=');
|
||||
}
|
||||
|
||||
static void Http_ParseContentLength(struct HttpRequest* req, const cc_string* value) {
|
||||
int contentLen = 0;
|
||||
Convert_ParseInt(value, &contentLen);
|
||||
|
||||
if (contentLen <= 0) return;
|
||||
req->contentLength = contentLen;
|
||||
}
|
||||
|
||||
/* Parses a HTTP header */
|
||||
static void Http_ParseHeader(struct HttpRequest* req, const cc_string* line) {
|
||||
static const cc_string httpVersion = String_FromConst("HTTP");
|
||||
cc_string name, value, parts[3];
|
||||
int numParts;
|
||||
|
||||
/* HTTP[version] [status code] [status reason] */
|
||||
if (String_CaselessStarts(line, &httpVersion)) {
|
||||
numParts = String_UNSAFE_Split(line, ' ', parts, 3);
|
||||
if (numParts >= 2) Convert_ParseInt(&parts[1], &req->statusCode);
|
||||
}
|
||||
/* For all other headers: name: value */
|
||||
if (!String_UNSAFE_Separate(line, ':', &name, &value)) return;
|
||||
|
||||
if (String_CaselessEqualsConst(&name, "ETag")) {
|
||||
String_CopyToRawArray(req->etag, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Content-Length")) {
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "X-Dropbox-Content-Length")) {
|
||||
/* dropbox stopped returning Content-Length header since switching to chunked transfer */
|
||||
/* https://www.dropboxforum.com/t5/Discuss-Dropbox-Developer-API/Dropbox-media-can-t-be-access-by-azure-blob/td-p/575458 */
|
||||
Http_ParseContentLength(req, &value);
|
||||
} else if (String_CaselessEqualsConst(&name, "Last-Modified")) {
|
||||
String_CopyToRawArray(req->lastModified, &value);
|
||||
} else if (req->cookies && String_CaselessEqualsConst(&name, "Set-Cookie")) {
|
||||
Http_ParseCookie(req, &value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds a http header to the request headers. */
|
||||
static void Http_AddHeader(struct HttpRequest* req, const char* key, const cc_string* value);
|
||||
|
||||
/* Adds all the appropriate headers for a request. */
|
||||
static void Http_SetRequestHeaders(struct HttpRequest* req) {
|
||||
static const cc_string contentType = String_FromConst("application/x-www-form-urlencoded");
|
||||
cc_string str, cookies; char cookiesBuffer[1024];
|
||||
int i;
|
||||
|
||||
if (req->lastModified[0]) {
|
||||
str = String_FromRawArray(req->lastModified);
|
||||
Http_AddHeader(req, "If-Modified-Since", &str);
|
||||
}
|
||||
if (req->etag[0]) {
|
||||
str = String_FromRawArray(req->etag);
|
||||
Http_AddHeader(req, "If-None-Match", &str);
|
||||
}
|
||||
|
||||
if (req->data) Http_AddHeader(req, "Content-Type", &contentType);
|
||||
if (!req->cookies || !req->cookies->count) return;
|
||||
|
||||
String_InitArray(cookies, cookiesBuffer);
|
||||
for (i = 0; i < req->cookies->count; i++) {
|
||||
if (i) String_AppendConst(&cookies, "; ");
|
||||
str = StringsBuffer_UNSAFE_Get(req->cookies, i);
|
||||
String_AppendString(&cookies, &str);
|
||||
}
|
||||
Http_AddHeader(req, "Cookie", &cookies);
|
||||
}
|
||||
|
||||
/* TODO: Rewrite to use a local variable instead */
|
||||
static cc_string* Http_GetUserAgent_UNSAFE(void) {
|
||||
static char userAgentBuffer[STRING_SIZE];
|
||||
static cc_string userAgent;
|
||||
|
||||
String_InitArray(userAgent, userAgentBuffer);
|
||||
String_AppendConst(&userAgent, GAME_APP_NAME);
|
||||
String_AppendConst(&userAgent, Platform_AppNameSuffix);
|
||||
return &userAgent;
|
||||
}
|
||||
|
||||
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------Common downloader code-------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
|
12
third_party/bearssl/config.h
vendored
12
third_party/bearssl/config.h
vendored
@ -32,18 +32,6 @@
|
||||
* non-zero integer (normally 1). If the macro is not defined, then
|
||||
* autodetection applies.
|
||||
*/
|
||||
|
||||
/* The x86 intrinsics seem to be incomplete compared to what aes_x86ni expects when compiling with NXDK */
|
||||
#ifdef NXDK
|
||||
#define BR_AES_X86NI 0
|
||||
#define BR_ENABLE_INTRINSICS 0
|
||||
#define BR_SSE2 0
|
||||
#endif
|
||||
|
||||
/* intrin.h doesn't exist in older TinyC */
|
||||
#if defined __TINYC__
|
||||
#define BR_INT128 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When BR_64 is enabled, 64-bit integer types are assumed to be
|
||||
|
24
third_party/bearssl/inner.h
vendored
24
third_party/bearssl/inner.h
vendored
@ -35,6 +35,30 @@
|
||||
#include "config.h"
|
||||
#include "bearssl.h"
|
||||
|
||||
/* ==== BEG ClassiCube specific ==== */
|
||||
static size_t br_strlen(const char* a) {
|
||||
int i = 0;
|
||||
while (*a++) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
#define br_memcpy memcpy
|
||||
#define br_memset memset
|
||||
#define br_memmove memmove
|
||||
|
||||
/* The x86 intrinsics seem to be incomplete compared to what aes_x86ni expects when compiling with NXDK */
|
||||
#ifdef NXDK
|
||||
#define BR_AES_X86NI 0
|
||||
#define BR_ENABLE_INTRINSICS 0
|
||||
#define BR_SSE2 0
|
||||
#endif
|
||||
|
||||
/* intrin.h doesn't exist in older TinyC */
|
||||
#if defined __TINYC__
|
||||
#define BR_INT128 0
|
||||
#endif
|
||||
/* ==== END ClassiCube specific ==== */
|
||||
|
||||
/*
|
||||
* On MSVC, disable the warning about applying unary minus on an
|
||||
* unsigned type: it is standard, we do it all the time, and for
|
||||
|
2
third_party/bearssl/ssl_client.c
vendored
2
third_party/bearssl/ssl_client.c
vendored
@ -64,7 +64,7 @@ br_ssl_client_reset(br_ssl_client_context *cc,
|
||||
if (server_name == NULL) {
|
||||
cc->eng.server_name[0] = 0;
|
||||
} else {
|
||||
n = strlen(server_name) + 1;
|
||||
n = br_strlen(server_name) + 1;
|
||||
if (n > sizeof cc->eng.server_name) {
|
||||
br_ssl_engine_fail(&cc->eng, BR_ERR_BAD_PARAM);
|
||||
return 0;
|
||||
|
10
third_party/bearssl/ssl_hs_client.c
vendored
10
third_party/bearssl/ssl_hs_client.c
vendored
@ -1246,7 +1246,7 @@ br_ssl_hs_client_run(void *t0ctx)
|
||||
/* copy-protocol-name */
|
||||
|
||||
size_t idx = T0_POP();
|
||||
size_t len = strlen(ENG->protocol_names[idx]);
|
||||
size_t len = br_strlen(ENG->protocol_names[idx]);
|
||||
memcpy(ENG->pad, ENG->protocol_names[idx], len);
|
||||
T0_PUSH(len);
|
||||
|
||||
@ -1346,7 +1346,7 @@ br_ssl_hs_client_run(void *t0ctx)
|
||||
}
|
||||
len = 6;
|
||||
for (u = 0; u < ENG->protocol_names_num; u ++) {
|
||||
len += 1 + strlen(ENG->protocol_names[u]);
|
||||
len += 1 + br_strlen(ENG->protocol_names[u]);
|
||||
}
|
||||
T0_PUSH(len);
|
||||
|
||||
@ -1591,10 +1591,10 @@ br_ssl_hs_client_run(void *t0ctx)
|
||||
}
|
||||
break;
|
||||
case 63: {
|
||||
/* strlen */
|
||||
/* br_strlen */
|
||||
|
||||
void *str = (unsigned char *)ENG + (size_t)T0_POP();
|
||||
T0_PUSH((uint32_t)strlen(str));
|
||||
T0_PUSH((uint32_t)br_strlen(str));
|
||||
|
||||
}
|
||||
break;
|
||||
@ -1766,7 +1766,7 @@ br_ssl_hs_client_run(void *t0ctx)
|
||||
const char *name;
|
||||
|
||||
name = ENG->protocol_names[u];
|
||||
if (len == strlen(name) && memcmp(ENG->pad, name, len) == 0) {
|
||||
if (len == br_strlen(name) && memcmp(ENG->pad, name, len) == 0) {
|
||||
T0_PUSH(u);
|
||||
T0_RET();
|
||||
}
|
||||
|
2
third_party/bearssl/x509_minimal.c
vendored
2
third_party/bearssl/x509_minimal.c
vendored
@ -1440,7 +1440,7 @@ br_x509_minimal_run(void *t0ctx)
|
||||
T0_PUSH(0);
|
||||
T0_RET();
|
||||
}
|
||||
n1 = strlen(CTX->server_name);
|
||||
n1 = br_strlen(CTX->server_name);
|
||||
n2 = CTX->pad[0];
|
||||
if (n1 == n2 && eqnocase(&CTX->pad[1], CTX->server_name, n1)) {
|
||||
T0_PUSHi(-1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user