From 51e4af543041e33f1495b6b0c49ff05d437f7eee Mon Sep 17 00:00:00 2001 From: emoose Date: Fri, 10 Jan 2020 22:55:19 +0000 Subject: [PATCH] [Kernel] Fix wide-printf functions not processing %ws format correctly This would break strings like memory://%.*ws, because the %ws would set FF_IsWide, but FF_IsWide is actually treated as an "is opposite encoding" flag. Since the function is already wide, that flag would make it think it's opposite encoding and it'd try reading the param as ASCII instead of Unicode... --- src/xenia/kernel/xboxkrnl/xboxkrnl_strings.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_strings.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_strings.cc index b5a4c9241..d5313ed7f 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_strings.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_strings.cc @@ -49,6 +49,9 @@ enum FormatFlags { FF_IsWide = 1 << 9, FF_IsSigned = 1 << 10, FF_ForceLeadingZero = 1 << 11, + // IsWide gets used as an "is opposite encoding" flag, but this flag means + // it's definitely wide + FF_IsAlwaysWide = 1 << 12, }; enum ArgumentSize { @@ -292,7 +295,7 @@ int32_t format_core(PPCContext* ppc_context, FormatData& data, ArgList& args, state = FS_Type; continue; } else if (c == 'w') { - flags |= FF_IsWide; + flags |= (FF_IsWide | FF_IsAlwaysWide); state = FS_Type; continue; } else if (c == 'I') { @@ -337,7 +340,7 @@ int32_t format_core(PPCContext* ppc_context, FormatData& data, ArgList& args, // functions and with C in wprintf functions." is_wide = false; } else { - is_wide = ((flags & FF_IsWide) != 0) ^ wide; + is_wide = (((flags & FF_IsWide) != 0) ^ wide) || (flags & FF_IsAlwaysWide) != 0; } auto value = args.get32(); @@ -552,7 +555,7 @@ int32_t format_core(PPCContext* ppc_context, FormatData& data, ArgList& args, // functions and with S in wprintf functions." is_wide = false; } else { - is_wide = ((flags & (FF_IsWide)) != 0) ^ wide; + is_wide = (((flags & (FF_IsWide)) != 0) ^ wide) || (flags & FF_IsAlwaysWide) != 0; } int32_t length;