Mikolaj Zalewski : ntdll: Manifests should be parsed as UTF-16 only if there is a BOM (with testcase ).
Alexandre Julliard
julliard at winehq.org
Thu Oct 18 07:59:35 CDT 2007
Module: wine
Branch: master
Commit: 9f4001f7e032305990871ea8ba03113dbafd23fb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9f4001f7e032305990871ea8ba03113dbafd23fb
Author: Mikolaj Zalewski <mikolajz at google.com>
Date: Wed Oct 17 13:36:34 2007 -0700
ntdll: Manifests should be parsed as UTF-16 only if there is a BOM (with testcase).
---
dlls/kernel32/tests/actctx.c | 76 +++++++++++++++++++++++++++++++++++-------
dlls/ntdll/actctx.c | 4 ++-
2 files changed, 67 insertions(+), 13 deletions(-)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c
index da1650b..e2e6b24 100644
--- a/dlls/kernel32/tests/actctx.c
+++ b/dlls/kernel32/tests/actctx.c
@@ -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;
}
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index 2021cb8..e26dc02 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -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 );
More information about the wine-cvs
mailing list