Skip to content

Commit

Permalink
Merge pull request #12263 from keymanapp/fix/developer/12262-ensure-c…
Browse files Browse the repository at this point in the history
…all-detects-invalid-store-in-kmcmplib-compiler

fix(developer): ensure call() detects invalid store in kmcmplib compiler
  • Loading branch information
markcsinclair authored Aug 26, 2024
2 parents 793ef93 + fca939b commit f5ddc4b
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
2 changes: 1 addition & 1 deletion developer/src/kmcmplib/src/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2310,11 +2310,11 @@ KMX_DWORD GetXStringImpl(PKMX_WCHAR tstr, PFILE_KEYBOARD fk, PKMX_WCHAR str, KMX
{
if (u16icmp(q, fk->dpStoreArray[i].szName) == 0) break;
}
if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist;

if (!kmcmp::IsValidCallStore(&fk->dpStoreArray[i])) return KmnCompilerMessages::ERROR_InvalidCall;
kmcmp::CheckStoreUsage(fk, i, FALSE, FALSE, TRUE);

if (i == fk->cxStoreArray) return KmnCompilerMessages::ERROR_StoreDoesNotExist;
tstr[mx++] = UC_SENTINEL;
tstr[mx++] = CODE_CALL;
tstr[mx++] = (KMX_WCHAR)i + 1;
Expand Down
88 changes: 88 additions & 0 deletions developer/src/kmcmplib/tests/gtest-compiler-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,94 @@ TEST_F(CompilerTest, GetXStringImpl_type_o_test) {
EXPECT_EQ(0, u16cmp(tstr_outs_space_after_valid, tstr));
}

// tests strings starting with 'c'
TEST_F(CompilerTest, GetXStringImpl_type_c_test) {
KMX_WCHAR tstr[128];
fileKeyboard.version = VERSION_60;
KMX_WCHAR str[LINESIZE];
KMX_WCHAR output[GLOBAL_BUFSIZE];
PKMX_WCHAR newp = nullptr;
PFILE_STORE file_store = new FILE_STORE[100];
fileKeyboard.cxStoreArray = 3u;
fileKeyboard.dpStoreArray = file_store;
file_store[1].fIsCall = TRUE;
file_store[1].dwSystemID = TSS_NONE;
u16cpy(file_store[0].szName, u"a");
u16cpy(file_store[1].szName, u"b");
u16cpy(file_store[2].szName, u"c");

// call, KmnCompilerMessages::ERROR_501FeatureOnly_Call
fileKeyboard.version = VERSION_50;
u16cpy(str, u"call");
EXPECT_EQ(KmnCompilerMessages::ERROR_501FeatureOnly_Call, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, KmnCompilerMessages::ERROR_CallInVirtualKeySection *** TODO ***

// call, no close delimiter => NULL
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call(");
EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidCall, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, empty delimiters => empty string
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call()");
EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidCall, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, space in delimiters (see I11814, I11937, #11910, #11894, #11938)
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call( )");
EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidCall, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, KmnCompilerMessages::ERROR_StoreDoesNotExist
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call(d)");
EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, KmnCompilerMessages::ERROR_StoreDoesNotExist, space before store
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call( d)");
EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, KmnCompilerMessages::ERROR_StoreDoesNotExist, space after store
fileKeyboard.version = VERSION_501;
u16cpy(str, u"call(d )");
EXPECT_EQ(KmnCompilerMessages::ERROR_StoreDoesNotExist, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, KmnCompilerMessages::ERROR_InvalidCall
fileKeyboard.version = VERSION_501;
file_store[1].dpString = (PKMX_WCHAR)u"*"; // cause IsValidCallStore() to fail
u16cpy(str, u"call(b)");
EXPECT_EQ(KmnCompilerMessages::ERROR_InvalidCall, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));

// call, valid
fileKeyboard.version = VERSION_501;
file_store[1].dpString = (PKMX_WCHAR)u"a.dll:A";
file_store[1].dwSystemID = TSS_NONE;
u16cpy(str, u"call(b)");
EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));
const KMX_WCHAR tstr_call_valid[] = { UC_SENTINEL, CODE_CALL, 2, 0 };
EXPECT_EQ(0, u16cmp(tstr_call_valid, tstr));
EXPECT_EQ(TSS_CALLDEFINITION, file_store[1].dwSystemID);

// call, space before store, valid
fileKeyboard.version = VERSION_501;
file_store[1].dpString = (PKMX_WCHAR)u"a.dll:A";
file_store[1].dwSystemID = TSS_NONE;
u16cpy(str, u"call( b)");
EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));
EXPECT_EQ(0, u16cmp(tstr_call_valid, tstr));
EXPECT_EQ(TSS_CALLDEFINITION, file_store[1].dwSystemID);

// call, space after store, valid (see I11937, #11938)
fileKeyboard.version = VERSION_501;
file_store[1].dpString = (PKMX_WCHAR)u"a.dll:A";
file_store[1].dwSystemID = TSS_NONE;
u16cpy(str, u"call(b )");
EXPECT_EQ(STATUS_Success, GetXStringImpl(tstr, &fileKeyboard, str, u"", output, 80, 0, &newp, FALSE));
EXPECT_EQ(0, u16cmp(tstr_call_valid, tstr));
EXPECT_EQ(TSS_CALLDEFINITION, file_store[1].dwSystemID);
}

// KMX_DWORD process_baselayout(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx)
// KMX_DWORD process_platform(PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx)
// KMX_DWORD process_if_synonym(KMX_DWORD dwSystemID, PFILE_KEYBOARD fk, PKMX_WCHAR q, PKMX_WCHAR tstr, int *mx)
Expand Down

0 comments on commit f5ddc4b

Please sign in to comment.