Skip to content

Commit 64c55cd

Browse files
Copilotprobonopd
andcommitted
Address code review feedback: improve error handling and type safety
- Add error handling for ftell() and malloc() failures in readFile() - Remove unnecessary #else block for deprecated glib function (always use new version) - Change sfs_mksquashfs to accept size_t instead of int for offset parameter - Handle negative contentLength from curl in fetch_runtime() - Validate offset before casting to long in read_file_offset_length() - Check snprintf return value for buffer overflow instead of reducing buffer size - Add limits.h include for LONG_MAX All changes improve code safety and correctness as suggested by @black-sliver. Co-authored-by: probonopd <[email protected]>
1 parent 696f67d commit 64c55cd

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

src/appimagetool.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static void die(const char *msg) {
9494

9595
/* Generate a squashfs filesystem using mksquashfs on the $PATH
9696
* execlp(), execvp(), and execvpe() search on the $PATH */
97-
int sfs_mksquashfs(char *source, char *destination, int offset) {
97+
int sfs_mksquashfs(char *source, char *destination, size_t offset) {
9898
pid_t pid = fork();
9999
if (pid == -1) {
100100
perror("sfs_mksquashfs fork() failed");
@@ -119,7 +119,7 @@ int sfs_mksquashfs(char *source, char *destination, int offset) {
119119
} else {
120120
// we are the child
121121
gchar* offset_string;
122-
offset_string = g_strdup_printf("%i", offset);
122+
offset_string = g_strdup_printf("%zu", offset);
123123

124124
guint sqfs_opts_len = sqfs_opts ? g_strv_length(sqfs_opts) : 0;
125125

@@ -464,9 +464,24 @@ bool readFile(char* filename, size_t* size, char** buffer) {
464464

465465
fseek(f, 0, SEEK_END);
466466
long fsize = ftell(f);
467+
if (fsize < 0) {
468+
// ftell failed
469+
fclose(f);
470+
*buffer = 0;
471+
*size = 0;
472+
return false;
473+
}
467474
fseek(f, 0, SEEK_SET);
468475

469476
char *indata = malloc((size_t)fsize);
477+
if (indata == NULL) {
478+
// malloc failed
479+
fclose(f);
480+
*buffer = 0;
481+
*size = 0;
482+
return false;
483+
}
484+
470485
fread(indata, (size_t)fsize, 1, f);
471486
fclose(f);
472487
*size = (size_t)fsize;
@@ -696,11 +711,7 @@ main (int argc, char *argv[])
696711
g_spawn_command_line_sync(command_line, &out, NULL, &exit_status, &error);
697712

698713
// g_spawn_command_line_sync might have set error already, in that case we don't want to overwrite
699-
#if GLIB_CHECK_VERSION(2, 70, 0)
700714
if (error != NULL || !g_spawn_check_wait_status(exit_status, &error)) {
701-
#else
702-
if (error != NULL || !g_spawn_check_exit_status(exit_status, &error)) {
703-
#endif
704715
if (error == NULL) {
705716
g_printerr("Failed to run 'git rev-parse --short HEAD, but failed to interpret GLib error state: %d\n", exit_status);
706717
} else {
@@ -777,8 +788,7 @@ main (int argc, char *argv[])
777788
gchar* arch = getArchName(archs);
778789
fprintf(stderr, "Using architecture %s\n", arch);
779790

780-
// Reserve space for version, arch, and ".AppImage" suffix (max ~50 chars)
781-
char app_name_for_filename[PATH_MAX - 50];
791+
char app_name_for_filename[PATH_MAX];
782792
{
783793
const char* const env_app_name = getenv("APPIMAGETOOL_APP_NAME");
784794
if (env_app_name != NULL) {
@@ -804,10 +814,15 @@ main (int argc, char *argv[])
804814
char dest_path[PATH_MAX];
805815

806816
// if $VERSION is specified, we embed it into the filename
817+
int ret;
807818
if (version_env != NULL) {
808-
snprintf(dest_path, sizeof(dest_path), "%s-%s-%s.AppImage", app_name_for_filename, version_env, arch);
819+
ret = snprintf(dest_path, sizeof(dest_path), "%s-%s-%s.AppImage", app_name_for_filename, version_env, arch);
809820
} else {
810-
snprintf(dest_path, sizeof(dest_path), "%s-%s.AppImage", app_name_for_filename, arch);
821+
ret = snprintf(dest_path, sizeof(dest_path), "%s-%s.AppImage", app_name_for_filename, arch);
822+
}
823+
824+
if (ret < 0 || (size_t)ret >= sizeof(dest_path)) {
825+
die("Destination filename too long");
811826
}
812827

813828
destination = strdup(dest_path);
@@ -932,7 +947,7 @@ main (int argc, char *argv[])
932947
if (verbose)
933948
printf("Size of the embedded runtime: %zu bytes\n", size);
934949

935-
int result = sfs_mksquashfs(source, destination, (int)size);
950+
int result = sfs_mksquashfs(source, destination, size);
936951
if(result != 0)
937952
die("sfs_mksquashfs error");
938953

src/appimagetool_fetch_runtime.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,14 @@ bool fetch_runtime(char *arch, size_t *size, char **buffer, bool verbose) {
280280
}
281281

282282
auto runtimeData = response.data();
283+
284+
// curl returns negative contentLength if size is not known
285+
if (response.contentLength() < 0) {
286+
std::cerr << "Error: content length not available from server" << std::endl;
287+
return false;
288+
}
283289

284-
if (runtimeData.size() != static_cast<std::vector<char>::size_type>(response.contentLength())) {
290+
if (runtimeData.size() != static_cast<size_t>(response.contentLength())) {
285291
std::cerr << "Error: downloaded data size of " << runtimeData.size()
286292
<< " does not match content-length of " << response.contentLength() << std::endl;
287293
return false;

src/elf.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdbool.h>
99
#include <memory.h>
1010
#include <sys/mman.h>
11+
#include <limits.h>
1112

1213
#include "light_elf.h"
1314
#include "light_byteswap.h"
@@ -177,6 +178,12 @@ char* read_file_offset_length(const char* fname, unsigned long offset, unsigned
177178
return NULL;
178179
}
179180

181+
// Validate offset can be safely cast to long
182+
if (offset > (unsigned long)LONG_MAX) {
183+
fclose(f);
184+
return NULL;
185+
}
186+
180187
fseek(f, (long)offset, SEEK_SET);
181188

182189
char* buffer = calloc(length + 1, sizeof(char));

0 commit comments

Comments
 (0)