Skip to content

Commit

Permalink
Allow Switch.Application "icon" to be larger than 131072 (0x20000) …
Browse files Browse the repository at this point in the history
…bytes
  • Loading branch information
TooTallNate committed Dec 13, 2024
1 parent 7f6e4d7 commit 66ceb15
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
5 changes: 5 additions & 0 deletions .changeset/three-chefs-sell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@nx.js/runtime": patch
---

Allow `Switch.Application` "icon" to be larger than 131072 (0x20000) bytes
47 changes: 32 additions & 15 deletions source/ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ nx_app_t *nx_get_app(JSContext *ctx, JSValueConst obj) {
static void finalizer_app(JSRuntime *rt, JSValue val) {
nx_app_t *app = JS_GetOpaque(val, nx_app_class_id);
if (app) {
if (app->icon) {
js_free_rt(rt, app->icon);
}
js_free_rt(rt, app);
}
}
Expand Down Expand Up @@ -84,11 +87,16 @@ static JSValue nx_ns_app_new(JSContext *ctx, JSValueConst this_val, int argc,

// Seek to the icon section offset and read the icon data
fseek(file, asset_header_offset + icon_section_offset, SEEK_SET);
fread(&data->data.icon, icon_section_size, 1, file);
data->icon = js_malloc(ctx, icon_section_size);
if (!data->icon) {
fclose(file);
return JS_EXCEPTION;
}
fread(data->icon, icon_section_size, 1, file);

// Seek to the nacp section offset and read the nacp data
fseek(file, asset_header_offset + nacp_section_offset, SEEK_SET);
fread(&data->data.nacp, nacp_section_size, 1, file);
fread(&data->nacp, nacp_section_size, 1, file);

free(asset_header);
fclose(file);
Expand All @@ -106,24 +114,35 @@ static JSValue nx_ns_app_new(JSContext *ctx, JSValueConst this_val, int argc,
u32 icon_section_size = *(u32 *)(asset_header + 0x10);
u32 nacp_section_offset = *(u32 *)(asset_header + 0x18);
u32 nacp_section_size = *(u32 *)(asset_header + 0x20);
memcpy(&data->data.icon, asset_header + icon_section_offset,
data->icon = js_mallocz(ctx, icon_section_size);
if (!data->icon) {
return JS_EXCEPTION;
}
memcpy(data->icon, asset_header + icon_section_offset,
icon_section_size);
memcpy(&data->data.nacp, asset_header + nacp_section_offset,
memcpy(&data->nacp, asset_header + nacp_section_offset,
nacp_section_size);
data->icon_size = icon_section_size;
loaded = true;
}

if (!loaded) {
size_t outSize;
NsApplicationControlData buf;
Result rc = nsGetApplicationControlData(
NsApplicationControlSource_Storage, application_id, &data->data,
sizeof(data->data), &outSize);
NsApplicationControlSource_Storage, application_id, &buf,
sizeof(NsApplicationControlData), &outSize);
if (R_FAILED(rc)) {
return nx_throw_libnx_error(ctx, rc,
"nsGetApplicationControlData()");
}
data->icon_size = outSize > 0 ? outSize - sizeof(data->data.nacp) : 0;
data->icon_size = outSize > 0 ? outSize - sizeof(buf.nacp) : 0;
data->icon = js_malloc(ctx, data->icon_size);
if (!data->icon) {
return JS_EXCEPTION;
}
memcpy(data->icon, &buf.icon, data->icon_size);
memcpy(&data->nacp, &buf.nacp, sizeof(NacpStruct));
}

JSValue app = JS_NewObjectClass(ctx, nx_app_class_id);
Expand All @@ -137,7 +156,7 @@ static JSValue nx_ns_app_id(JSContext *ctx, JSValueConst this_val, int argc,
if (!app) {
return JS_EXCEPTION;
}
return JS_NewBigUint64(ctx, app->data.nacp.presence_group_id);
return JS_NewBigUint64(ctx, app->nacp.presence_group_id);
}

static JSValue nx_ns_app_nacp(JSContext *ctx, JSValueConst this_val, int argc,
Expand All @@ -146,8 +165,7 @@ static JSValue nx_ns_app_nacp(JSContext *ctx, JSValueConst this_val, int argc,
if (!app) {
return JS_EXCEPTION;
}
return JS_NewArrayBufferCopy(ctx, (uint8_t *)&app->data.nacp,
sizeof(app->data.nacp));
return JS_NewArrayBufferCopy(ctx, (uint8_t *)&app->nacp, sizeof(app->nacp));
}

static JSValue nx_ns_app_icon(JSContext *ctx, JSValueConst this_val, int argc,
Expand All @@ -159,8 +177,7 @@ static JSValue nx_ns_app_icon(JSContext *ctx, JSValueConst this_val, int argc,
if (app->icon_size <= 0) {
return JS_UNDEFINED;
}
return JS_NewArrayBufferCopy(ctx, (uint8_t *)&app->data.icon,
app->icon_size);
return JS_NewArrayBufferCopy(ctx, (uint8_t *)app->icon, app->icon_size);
}

static JSValue nx_ns_app_name(JSContext *ctx, JSValueConst this_val, int argc,
Expand All @@ -170,7 +187,7 @@ static JSValue nx_ns_app_name(JSContext *ctx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
NacpLanguageEntry *langEntry;
Result rc = nacpGetLanguageEntry(&app->data.nacp, &langEntry);
Result rc = nacpGetLanguageEntry(&app->nacp, &langEntry);
if (R_FAILED(rc)) {
return nx_throw_libnx_error(ctx, rc, "nacpGetLanguageEntry()");
}
Expand All @@ -188,7 +205,7 @@ static JSValue nx_ns_app_author(JSContext *ctx, JSValueConst this_val, int argc,
return JS_EXCEPTION;
}
NacpLanguageEntry *langEntry;
Result rc = nacpGetLanguageEntry(&app->data.nacp, &langEntry);
Result rc = nacpGetLanguageEntry(&app->nacp, &langEntry);
if (R_FAILED(rc)) {
return nx_throw_libnx_error(ctx, rc, "nacpGetLanguageEntry()");
}
Expand Down Expand Up @@ -227,7 +244,7 @@ static JSValue nx_ns_app_version(JSContext *ctx, JSValueConst this_val,
if (!app) {
return JS_EXCEPTION;
}
return JS_NewString(ctx, app->data.nacp.display_version);
return JS_NewString(ctx, app->nacp.display_version);
}

static JSValue nx_ns_app_init(JSContext *ctx, JSValueConst this_val, int argc,
Expand Down
3 changes: 2 additions & 1 deletion source/ns.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#include "types.h"

typedef struct {
void *icon;
size_t icon_size;
NsApplicationControlData data;
NacpStruct nacp;
} nx_app_t;

nx_app_t *nx_get_app(JSContext *ctx, JSValueConst obj);
Expand Down

0 comments on commit 66ceb15

Please sign in to comment.