mirror of https://github.com/mgba-emu/mgba.git
Util: Start cleaning up some bounded string copies
This commit is contained in:
parent
3be21bf595
commit
2f066a9790
|
@ -281,6 +281,7 @@ include(CheckFunctionExists)
|
|||
include(CheckIncludeFiles)
|
||||
check_function_exists(strdup HAVE_STRDUP)
|
||||
check_function_exists(strndup HAVE_STRNDUP)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
if(NOT DEFINED PSP2)
|
||||
check_function_exists(localtime_r HAVE_LOCALTIME_R)
|
||||
endif()
|
||||
|
@ -359,6 +360,10 @@ if(HAVE_STRNDUP)
|
|||
list(APPEND FUNCTION_DEFINES HAVE_STRNDUP)
|
||||
endif()
|
||||
|
||||
if(HAVE_STRLCPY)
|
||||
list(APPEND FUNCTION_DEFINES HAVE_STRLCPY)
|
||||
endif()
|
||||
|
||||
if(HAVE_LOCALTIME_R)
|
||||
list(APPEND FUNCTION_DEFINES HAVE_LOCALTIME_R)
|
||||
endif()
|
||||
|
|
|
@ -19,6 +19,10 @@ char* strndup(const char* start, size_t len);
|
|||
char* strdup(const char* str);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char* restrict dst, const char* restrict src, size_t dstsize);
|
||||
#endif
|
||||
|
||||
char* strnrstr(const char* restrict s1, const char* restrict s2, size_t len);
|
||||
bool endswith(const char* restrict s1, const char* restrict end);
|
||||
bool startswith(const char* restrict s1, const char* restrict start);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/internal/arm/decoder.h>
|
||||
|
||||
#include <mgba/internal/arm/decoder-inlines.h>
|
||||
#include <mgba-util/string.h>
|
||||
|
||||
#define ADVANCE(AMOUNT) \
|
||||
if (AMOUNT >= blen) { \
|
||||
|
@ -45,22 +46,22 @@ static const char* _armConditions[] = {
|
|||
static int _decodeRegister(int reg, char* buffer, int blen) {
|
||||
switch (reg) {
|
||||
case ARM_SP:
|
||||
strncpy(buffer, "sp", blen - 1);
|
||||
strlcpy(buffer, "sp", blen);
|
||||
return 2;
|
||||
case ARM_LR:
|
||||
strncpy(buffer, "lr", blen - 1);
|
||||
strlcpy(buffer, "lr", blen);
|
||||
return 2;
|
||||
case ARM_PC:
|
||||
strncpy(buffer, "pc", blen - 1);
|
||||
strlcpy(buffer, "pc", blen);
|
||||
return 2;
|
||||
case ARM_CPSR:
|
||||
strncpy(buffer, "cpsr", blen - 1);
|
||||
strlcpy(buffer, "cpsr", blen);
|
||||
return 4;
|
||||
case ARM_SPSR:
|
||||
strncpy(buffer, "spsr", blen - 1);
|
||||
strlcpy(buffer, "spsr", blen);
|
||||
return 4;
|
||||
default:
|
||||
return snprintf(buffer, blen - 1, "r%i", reg);
|
||||
return snprintf(buffer, blen, "r%i", reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +70,7 @@ static int _decodeRegisterList(int list, char* buffer, int blen) {
|
|||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
strncpy(buffer, "{", blen - 1);
|
||||
strlcpy(buffer, "{", blen);
|
||||
ADVANCE(1);
|
||||
int i;
|
||||
int start = -1;
|
||||
|
@ -86,12 +87,12 @@ static int _decodeRegisterList(int list, char* buffer, int blen) {
|
|||
if (end > start) {
|
||||
written = _decodeRegister(start, buffer, blen);
|
||||
ADVANCE(written);
|
||||
strncpy(buffer, "-", blen - 1);
|
||||
strlcpy(buffer, "-", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
written = _decodeRegister(end, buffer, blen);
|
||||
ADVANCE(written);
|
||||
strncpy(buffer, ",", blen - 1);
|
||||
strlcpy(buffer, ",", blen);
|
||||
ADVANCE(1);
|
||||
start = i;
|
||||
end = i;
|
||||
|
@ -103,13 +104,13 @@ static int _decodeRegisterList(int list, char* buffer, int blen) {
|
|||
if (end > start) {
|
||||
written = _decodeRegister(start, buffer, blen);
|
||||
ADVANCE(written);
|
||||
strncpy(buffer, "-", blen - 1);
|
||||
strlcpy(buffer, "-", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
written = _decodeRegister(end, buffer, blen);
|
||||
ADVANCE(written);
|
||||
}
|
||||
strncpy(buffer, "}", blen - 1);
|
||||
strlcpy(buffer, "}", blen);
|
||||
ADVANCE(1);
|
||||
return total;
|
||||
}
|
||||
|
@ -119,29 +120,29 @@ static int _decodePSR(int psrBits, char* buffer, int blen) {
|
|||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
strncpy(buffer, "_", blen - 1);
|
||||
strlcpy(buffer, "_", blen);
|
||||
ADVANCE(1);
|
||||
if (psrBits & ARM_PSR_C) {
|
||||
strncpy(buffer, "c", blen - 1);
|
||||
strlcpy(buffer, "c", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (psrBits & ARM_PSR_X) {
|
||||
strncpy(buffer, "x", blen - 1);
|
||||
strlcpy(buffer, "x", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (psrBits & ARM_PSR_S) {
|
||||
strncpy(buffer, "s", blen - 1);
|
||||
strlcpy(buffer, "s", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (psrBits & ARM_PSR_F) {
|
||||
strncpy(buffer, "f", blen - 1);
|
||||
strlcpy(buffer, "f", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static int _decodePCRelative(uint32_t address, uint32_t pc, char* buffer, int blen) {
|
||||
return snprintf(buffer, blen - 1, "$%08X", address + pc);
|
||||
return snprintf(buffer, blen, "$%08X", address + pc);
|
||||
}
|
||||
|
||||
static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, int blen) {
|
||||
|
@ -149,7 +150,7 @@ static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, in
|
|||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
strncpy(buffer, "[", blen - 1);
|
||||
strlcpy(buffer, "[", blen);
|
||||
ADVANCE(1);
|
||||
int written;
|
||||
if (memory.format & ARM_MEMORY_REGISTER_BASE) {
|
||||
|
@ -160,26 +161,26 @@ static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, in
|
|||
written = _decodeRegister(memory.baseReg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
if (memory.format & (ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_IMMEDIATE_OFFSET) && !(memory.format & ARM_MEMORY_POST_INCREMENT)) {
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (memory.format & ARM_MEMORY_POST_INCREMENT) {
|
||||
strncpy(buffer, "], ", blen - 1);
|
||||
strlcpy(buffer, "], ", blen);
|
||||
ADVANCE(3);
|
||||
}
|
||||
if (memory.format & ARM_MEMORY_IMMEDIATE_OFFSET && memory.baseReg != ARM_PC) {
|
||||
if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
|
||||
written = snprintf(buffer, blen - 1, "#-%i", memory.offset.immediate);
|
||||
written = snprintf(buffer, blen, "#-%i", memory.offset.immediate);
|
||||
ADVANCE(written);
|
||||
} else {
|
||||
written = snprintf(buffer, blen - 1, "#%i", memory.offset.immediate);
|
||||
written = snprintf(buffer, blen, "#%i", memory.offset.immediate);
|
||||
ADVANCE(written);
|
||||
}
|
||||
} else if (memory.format & ARM_MEMORY_REGISTER_OFFSET) {
|
||||
if (memory.format & ARM_MEMORY_OFFSET_SUBTRACT) {
|
||||
strncpy(buffer, "-", blen - 1);
|
||||
strlcpy(buffer, "-", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
written = _decodeRegister(memory.offset.reg, buffer, blen);
|
||||
|
@ -191,11 +192,11 @@ static int _decodeMemory(struct ARMMemoryAccess memory, int pc, char* buffer, in
|
|||
}
|
||||
|
||||
if (!(memory.format & ARM_MEMORY_POST_INCREMENT)) {
|
||||
strncpy(buffer, "]", blen - 1);
|
||||
strlcpy(buffer, "]", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if ((memory.format & (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) == (ARM_MEMORY_PRE_INCREMENT | ARM_MEMORY_WRITEBACK)) {
|
||||
strncpy(buffer, "!", blen - 1);
|
||||
strlcpy(buffer, "!", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
return total;
|
||||
|
@ -206,33 +207,33 @@ static int _decodeShift(union ARMOperand op, bool reg, char* buffer, int blen) {
|
|||
return 0;
|
||||
}
|
||||
int total = 0;
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
int written;
|
||||
switch (op.shifterOp) {
|
||||
case ARM_SHIFT_LSL:
|
||||
strncpy(buffer, "lsl ", blen - 1);
|
||||
strlcpy(buffer, "lsl ", blen);
|
||||
ADVANCE(4);
|
||||
break;
|
||||
case ARM_SHIFT_LSR:
|
||||
strncpy(buffer, "lsr ", blen - 1);
|
||||
strlcpy(buffer, "lsr ", blen);
|
||||
ADVANCE(4);
|
||||
break;
|
||||
case ARM_SHIFT_ASR:
|
||||
strncpy(buffer, "asr ", blen - 1);
|
||||
strlcpy(buffer, "asr ", blen);
|
||||
ADVANCE(4);
|
||||
break;
|
||||
case ARM_SHIFT_ROR:
|
||||
strncpy(buffer, "ror ", blen - 1);
|
||||
strlcpy(buffer, "ror ", blen);
|
||||
ADVANCE(4);
|
||||
break;
|
||||
case ARM_SHIFT_RRX:
|
||||
strncpy(buffer, "rrx", blen - 1);
|
||||
strlcpy(buffer, "rrx", blen);
|
||||
ADVANCE(3);
|
||||
return total;
|
||||
}
|
||||
if (!reg) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", op.shifterImm);
|
||||
written = snprintf(buffer, blen, "#%i", op.shifterImm);
|
||||
} else {
|
||||
written = _decodeRegister(op.shifterReg, buffer, blen);
|
||||
}
|
||||
|
@ -369,7 +370,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
default:
|
||||
break;
|
||||
}
|
||||
written = snprintf(buffer, blen - 1, "%s%s%s ", mnemonic, cond, flags);
|
||||
written = snprintf(buffer, blen, "%s%s%s ", mnemonic, cond, flags);
|
||||
ADVANCE(written);
|
||||
|
||||
switch (info->mnemonic) {
|
||||
|
@ -378,15 +379,15 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
written = _decodeRegister(info->memory.baseReg, buffer, blen);
|
||||
ADVANCE(written);
|
||||
if (info->memory.format & ARM_MEMORY_WRITEBACK) {
|
||||
strncpy(buffer, "!", blen - 1);
|
||||
strlcpy(buffer, "!", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
written = _decodeRegisterList(info->op1.immediate, buffer, blen);
|
||||
ADVANCE(written);
|
||||
if (info->memory.format & ARM_MEMORY_SPSR_SWAP) {
|
||||
strncpy(buffer, "^", blen - 1);
|
||||
strlcpy(buffer, "^", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
break;
|
||||
|
@ -399,7 +400,7 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
break;
|
||||
default:
|
||||
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_1) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", info->op1.immediate);
|
||||
written = snprintf(buffer, blen, "#%i", info->op1.immediate);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_MEMORY_1) {
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
|
@ -420,11 +421,11 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_2) {
|
||||
strncpy(buffer, ", ", blen);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_2) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", info->op2.immediate);
|
||||
written = snprintf(buffer, blen, "#%i", info->op2.immediate);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_MEMORY_2) {
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
|
@ -441,11 +442,11 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_3) {
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_3) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", info->op3.immediate);
|
||||
written = snprintf(buffer, blen, "#%i", info->op3.immediate);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_MEMORY_3) {
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
|
@ -462,11 +463,11 @@ int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, i
|
|||
ADVANCE(written);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_4) {
|
||||
strncpy(buffer, ", ", blen - 1);
|
||||
strlcpy(buffer, ", ", blen);
|
||||
ADVANCE(2);
|
||||
}
|
||||
if (info->operandFormat & ARM_OPERAND_IMMEDIATE_4) {
|
||||
written = snprintf(buffer, blen - 1, "#%i", info->op4.immediate);
|
||||
written = snprintf(buffer, blen, "#%i", info->op4.immediate);
|
||||
ADVANCE(written);
|
||||
} else if (info->operandFormat & ARM_OPERAND_MEMORY_4) {
|
||||
written = _decodeMemory(info->memory, pc, buffer, blen);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <mgba/internal/sm83/emitter-sm83.h>
|
||||
#include <mgba/internal/sm83/sm83.h>
|
||||
#include <mgba-util/string.h>
|
||||
|
||||
typedef size_t (*SM83Decoder)(uint8_t opcode, struct SM83InstructionInfo* info);
|
||||
|
||||
|
@ -504,39 +505,39 @@ static int _decodeOperand(struct SM83Operand op, uint16_t pc, char* buffer, int
|
|||
return 0;
|
||||
}
|
||||
|
||||
strncpy(buffer, " ", blen - 1);
|
||||
strlcpy(buffer, " ", blen);
|
||||
ADVANCE(1);
|
||||
|
||||
if (op.flags & SM83_OP_FLAG_MEMORY) {
|
||||
strncpy(buffer, "[", blen - 1);
|
||||
strlcpy(buffer, "[", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (op.reg) {
|
||||
int written = snprintf(buffer, blen - 1, "%s", _sm83Registers[op.reg]);
|
||||
int written = snprintf(buffer, blen, "%s", _sm83Registers[op.reg]);
|
||||
ADVANCE(written);
|
||||
} else {
|
||||
int written;
|
||||
if (op.flags & SM83_OP_FLAG_RELATIVE) {
|
||||
written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
|
||||
written = snprintf(buffer, blen, "$%04X", pc + (int8_t) op.immediate);
|
||||
} else {
|
||||
written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
|
||||
written = snprintf(buffer, blen, "$%02X", op.immediate);
|
||||
}
|
||||
ADVANCE(written);
|
||||
if (op.reg) {
|
||||
strncpy(buffer, "+", blen - 1);
|
||||
strlcpy(buffer, "+", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
}
|
||||
if (op.flags & SM83_OP_FLAG_INCREMENT) {
|
||||
strncpy(buffer, "+", blen - 1);
|
||||
strlcpy(buffer, "+", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (op.flags & SM83_OP_FLAG_DECREMENT) {
|
||||
strncpy(buffer, "-", blen - 1);
|
||||
strlcpy(buffer, "-", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (op.flags & SM83_OP_FLAG_MEMORY) {
|
||||
strncpy(buffer, "]", blen - 1);
|
||||
strlcpy(buffer, "]", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
return total;
|
||||
|
@ -548,15 +549,15 @@ int SM83Disassemble(struct SM83InstructionInfo* info, uint16_t pc, char* buffer,
|
|||
int total = 0;
|
||||
const char* cond = _sm83Conditions[info->condition];
|
||||
|
||||
written = snprintf(buffer, blen - 1, "%s", mnemonic);
|
||||
written = snprintf(buffer, blen, "%s", mnemonic);
|
||||
ADVANCE(written);
|
||||
|
||||
if (cond) {
|
||||
written = snprintf(buffer, blen - 1, " %s", cond);
|
||||
written = snprintf(buffer, blen, " %s", cond);
|
||||
ADVANCE(written);
|
||||
|
||||
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
|
||||
strncpy(buffer, ",", blen - 1);
|
||||
strlcpy(buffer, ",", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
}
|
||||
|
@ -568,7 +569,7 @@ int SM83Disassemble(struct SM83InstructionInfo* info, uint16_t pc, char* buffer,
|
|||
|
||||
if (info->op2.reg || (!info->op1.immediate && info->opcodeSize > 1 && info->opcode[0] != 0xCB)) {
|
||||
if (written) {
|
||||
strncpy(buffer, ",", blen - 1);
|
||||
strlcpy(buffer, ",", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
written = _decodeOperand(info->op2, pc, buffer, blen);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <mgba-util/gui/font.h>
|
||||
#include <mgba-util/gui/menu.h>
|
||||
#include <mgba-util/string.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -200,7 +201,7 @@ bool GUISelectFile(struct GUIParams* params, char* outPath, size_t outLen, bool
|
|||
_cleanFiles(&menu.items);
|
||||
GUIMenuItemListDeinit(&menu.items);
|
||||
menu.items = newFiles;
|
||||
strncpy(params->currentPath, outPath, PATH_MAX);
|
||||
strlcpy(params->currentPath, outPath, PATH_MAX);
|
||||
}
|
||||
}
|
||||
params->fileIndex = 0;
|
||||
|
|
|
@ -31,6 +31,23 @@ char* strdup(const char* str) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char* restrict dst, const char* restrict src, size_t dstsize) {
|
||||
size_t i = 0;
|
||||
for (; src[i] && dstsize > 1; ++i) {
|
||||
dst[i] = src[i];
|
||||
--dstsize;
|
||||
}
|
||||
if (dstsize) {
|
||||
dst[i] = '\0';
|
||||
}
|
||||
while (src[i]) {
|
||||
++i;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* strnrstr(const char* restrict haystack, const char* restrict needle, size_t len) {
|
||||
char* last = 0;
|
||||
const char* next = haystack;
|
||||
|
|
Loading…
Reference in New Issue