diff --git a/CMakeLists.txt b/CMakeLists.txt index 7faef50e0..1cabb0887 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/include/mgba-util/string.h b/include/mgba-util/string.h index af8375cca..306a35257 100644 --- a/include/mgba-util/string.h +++ b/include/mgba-util/string.h @@ -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); diff --git a/src/arm/decoder.c b/src/arm/decoder.c index b95ff1126..8ebdbcaa0 100644 --- a/src/arm/decoder.c +++ b/src/arm/decoder.c @@ -6,6 +6,7 @@ #include #include +#include #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); diff --git a/src/sm83/decoder.c b/src/sm83/decoder.c index 949a8119a..7ad565d68 100644 --- a/src/sm83/decoder.c +++ b/src/sm83/decoder.c @@ -7,6 +7,7 @@ #include #include +#include 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); diff --git a/src/util/gui/file-select.c b/src/util/gui/file-select.c index 2e6abaed5..1d75e88b9 100644 --- a/src/util/gui/file-select.c +++ b/src/util/gui/file-select.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -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; diff --git a/src/util/string.c b/src/util/string.c index 46e52fba7..102a8cfbc 100644 --- a/src/util/string.c +++ b/src/util/string.c @@ -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;