From efd4373a5621d5bea134dfeffe1766d8b63e7941 Mon Sep 17 00:00:00 2001 From: Rangi Date: Mon, 30 Mar 2026 19:45:44 -0400 Subject: [PATCH] Check for a SDAS "Def" or "Ref" line before reading a subsequent integer Without checking `token[0]` through `token[2], `readInt` starting at `&token[3]` could go out of bounds on a badly-formed SDAS .rel object file --- src/link/sdas_obj.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/link/sdas_obj.cpp b/src/link/sdas_obj.cpp index 31bb8d61..35dd5b25 100644 --- a/src/link/sdas_obj.cpp +++ b/src/link/sdas_obj.cpp @@ -381,6 +381,12 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f expectNext(nullptr, 'S'); + // Expected format: /[DR]ef[0-9A-F]+/i + if ((token[0] != 'D' && token[0] != 'd' && token[0] != 'R' && token[0] != 'r') + || token[1] != 'e' || token[2] != 'f') { + fatalAt(where, "'S' line is neither \"Def\" nor \"Ref\""); + } + if (int32_t value = readInt(where, &token[3], numberBase); !fileSections.empty()) { // Symbols in sections are labels; their value is an offset Section *section = fileSections.back().section.get(); @@ -395,15 +401,13 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f symbol.data = value; } - // Expected format: /[DR]ef[0-9A-F]+/i if (token[0] == 'R' || token[0] == 'r') { + // "Ref" symbols are imported symbol.type = SYMTYPE_IMPORT; sym_AddSymbol(symbol); // TODO: hard error if the rest is not zero - } else if (token[0] != 'D' && token[0] != 'd') { - fatalAt(where, "'S' line is neither \"Def\" nor \"Ref\""); } else { - // All symbols are exported + // "Def" symbols are exported symbol.type = SYMTYPE_EXPORT; Symbol const *other = sym_GetSymbol(symbol.name); @@ -440,9 +444,6 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f // It's fine to keep modifying the symbol after `AddSymbol`, only // the name must not be modified } - if (strncasecmp(&token[1], "ef", literal_strlen("ef")) != 0) { - fatalAt(where, "'S' line is neither \"Def\" nor \"Ref\""); - } if (!fileSections.empty()) { fileSections.back().section->symbols.push_back(&symbol);