ntdll: Manifests should be parsed as UTF-16 only if there is a BOM (with testcase).

This commit is contained in:
Mikolaj Zalewski 2007-10-17 13:36:34 -07:00 committed by Alexandre Julliard
parent e361c0d284
commit 9f4001f7e0
2 changed files with 67 additions and 13 deletions

View File

@ -180,7 +180,7 @@ static DWORD strlen_aw(const char *str)
return MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0) - 1;
}
static BOOL create_manifest_file(const char *filename, const char *manifest,
static BOOL create_manifest_file(const char *filename, const char *manifest, int manifest_len,
const char *depfile, const char *depmanifest)
{
DWORD size;
@ -190,12 +190,15 @@ static BOOL create_manifest_file(const char *filename, const char *manifest,
MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
GetFullPathNameW(path, sizeof(manifest_path)/sizeof(WCHAR), manifest_path, NULL);
if (manifest_len == -1)
manifest_len = strlen(manifest);
file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
if(file == INVALID_HANDLE_VALUE)
return FALSE;
WriteFile(file, manifest, strlen(manifest), &size, NULL);
WriteFile(file, manifest, manifest_len, &size, NULL);
CloseHandle(file);
if (depmanifest)
@ -213,6 +216,19 @@ static BOOL create_manifest_file(const char *filename, const char *manifest,
return TRUE;
}
static BOOL create_wide_manifest(const char *filename, const char *manifest, BOOL fBOM)
{
WCHAR *wmanifest = HeapAlloc(GetProcessHeap(), 0, (strlen(manifest)+2) * sizeof(WCHAR));
BOOL ret;
int offset = (fBOM ? 0 : 1);
MultiByteToWideChar(CP_ACP, 0, manifest, -1, &wmanifest[1], (strlen(manifest)+1) * sizeof(WCHAR));
wmanifest[0] = 0xfeff;
ret = create_manifest_file(filename, (char *)&wmanifest[offset], (strlen(manifest)+1-offset) * sizeof(WCHAR), NULL, NULL);
HeapFree(GetProcessHeap(), 0, wmanifest);
return ret;
}
typedef struct {
ULONG format_version;
ULONG assembly_cnt;
@ -581,7 +597,7 @@ static void test_create_and_fail(const char *manifest, const char *depmanifest,
actctx.cbSize = sizeof(ACTCTXW);
actctx.lpSource = path;
create_manifest_file("bad.manifest", manifest, "testdep.manifest", depmanifest);
create_manifest_file("bad.manifest", manifest, -1, "testdep.manifest", depmanifest);
handle = pCreateActCtxW(&actctx);
if (todo) todo_wine
{
@ -598,6 +614,26 @@ static void test_create_and_fail(const char *manifest, const char *depmanifest,
DeleteFileA("testdep.manifest");
}
static void test_create_wide_and_fail(const char *manifest, BOOL fBOM)
{
ACTCTXW actctx;
HANDLE handle;
WCHAR path[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, "bad.manifest", -1, path, MAX_PATH );
memset(&actctx, 0, sizeof(ACTCTXW));
actctx.cbSize = sizeof(ACTCTXW);
actctx.lpSource = path;
create_wide_manifest("bad.manifest", manifest, fBOM);
handle = pCreateActCtxW(&actctx);
ok(handle == INVALID_HANDLE_VALUE, "handle != INVALID_HANDLE_VALUE\n");
ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX, "GetLastError == %u\n", GetLastError());
if (handle != INVALID_HANDLE_VALUE) pReleaseActCtx( handle );
DeleteFileA("bad.manifest");
}
static void test_create_fail(void)
{
ACTCTXW actctx;
@ -629,6 +665,8 @@ static void test_create_fail(void)
test_create_and_fail(wrong_manifest7, NULL, 1 );
trace("wrong_manifest8\n");
test_create_and_fail(wrong_manifest8, NULL, 0 );
trace("UTF-16 manifest1 without BOM\n");
test_create_wide_and_fail(manifest1, FALSE );
trace("manifest2\n");
test_create_and_fail(manifest2, NULL, 0 );
trace("manifest2+depmanifest1\n");
@ -822,7 +860,7 @@ static void test_actctx(void)
pReleaseActCtx(handle);
}
if(!create_manifest_file("test1.manifest", manifest1, NULL, NULL)) {
if(!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) {
skip("Could not create manifest file\n");
return;
}
@ -845,7 +883,7 @@ static void test_actctx(void)
pReleaseActCtx(handle);
}
if(!create_manifest_file("test2.manifest", manifest2, "testdep.manifest", testdep_manifest1)) {
if(!create_manifest_file("test2.manifest", manifest2, -1, "testdep.manifest", testdep_manifest1)) {
skip("Could not create manifest file\n");
return;
}
@ -862,7 +900,7 @@ static void test_actctx(void)
pReleaseActCtx(handle);
}
if(!create_manifest_file("test3.manifest", manifest2, "testdep.manifest", testdep_manifest2)) {
if(!create_manifest_file("test3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest2)) {
skip("Could not create manifest file\n");
return;
}
@ -891,7 +929,7 @@ static void test_actctx(void)
trace("manifest2 depmanifest3\n");
if(!create_manifest_file("test2-3.manifest", manifest2, "testdep.manifest", testdep_manifest3)) {
if(!create_manifest_file("test2-3.manifest", manifest2, -1, "testdep.manifest", testdep_manifest3)) {
skip("Could not create manifest file\n");
return;
}
@ -920,7 +958,7 @@ static void test_actctx(void)
trace("manifest3\n");
if(!create_manifest_file("test3.manifest", manifest3, NULL, NULL)) {
if(!create_manifest_file("test3.manifest", manifest3, -1, NULL, NULL)) {
skip("Could not create manifest file\n");
return;
}
@ -945,7 +983,7 @@ static void test_actctx(void)
trace("manifest4\n");
if(!create_manifest_file("test4.manifest", manifest4, NULL, NULL)) {
if(!create_manifest_file("test4.manifest", manifest4, -1, NULL, NULL)) {
skip("Could not create manifest file\n");
return;
}
@ -965,8 +1003,7 @@ static void test_actctx(void)
CreateDirectoryW(work_dir_subdir, NULL);
if (SetCurrentDirectoryW(work_dir_subdir))
{
/* the lpAddDirPath will point to the directory with the manifest */
if(!create_manifest_file("..\\test1.manifest", manifest1, NULL, NULL)) {
if(!create_manifest_file("..\\test1.manifest", manifest1, -1, NULL, NULL)) {
skip("Could not create manifest file\n");
return;
}
@ -982,6 +1019,21 @@ static void test_actctx(void)
else
skip("Couldn't change directory\n");
RemoveDirectoryW(work_dir_subdir);
trace("UTF-16 manifest1, with BOM\n");
if(!create_wide_manifest("test1.manifest", manifest1, TRUE)) {
skip("Could not create manifest file\n");
return;
}
handle = test_create("test1.manifest", manifest1);
DeleteFileA("test1.manifest");
if (handle != INVALID_HANDLE_VALUE) {
test_detailed_info(handle, &detailed_info1);
test_info_in_assembly(handle, 1, &manifest1_info);
pReleaseActCtx(handle);
}
}
static void test_app_manifest(void)
@ -1011,7 +1063,7 @@ static void run_child_process(void)
GetModuleFileNameA(NULL, path, MAX_PATH);
strcat(path, ".manifest");
if(!create_manifest_file(path, manifest1, NULL, NULL)) {
if(!create_manifest_file(path, manifest1, -1, NULL, NULL)) {
skip("Could not create manifest file\n");
return;
}

View File

@ -1484,6 +1484,7 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
xmlbuf_t xmlbuf;
NTSTATUS status;
struct assembly *assembly;
int unicode_tests;
TRACE( "parsing manifest loaded from %s base dir %s\n", debugstr_w(filename), debugstr_w(directory) );
@ -1497,7 +1498,8 @@ static NTSTATUS parse_manifest( struct actctx_loader* acl, struct assembly_ident
assembly->manifest.type = assembly->manifest.info ? ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE
: ACTIVATION_CONTEXT_PATH_TYPE_NONE;
if (!RtlIsTextUnicode( buffer, size, NULL ))
unicode_tests = IS_TEXT_UNICODE_SIGNATURE;
if (!RtlIsTextUnicode( buffer, size, &unicode_tests ))
{
/* let's assume utf-8 for now */
int len = wine_utf8_mbstowcs( 0, buffer, size, NULL, 0 );