Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e2ba5dce
Commit
e2ba5dce
authored
May 12, 2011
by
Hans Leidekker
Committed by
Alexandre Julliard
May 12, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Handle embedded nulls in text archives.
parent
b55cbe8d
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
76 additions
and
24 deletions
+76
-24
database.c
dlls/msi/database.c
+42
-24
db.c
dlls/msi/tests/db.c
+34
-0
No files found.
dlls/msi/database.c
View file @
e2ba5dce
...
@@ -509,7 +509,7 @@ end:
...
@@ -509,7 +509,7 @@ end:
return
r
;
return
r
;
}
}
static
LPWSTR
msi_read_text_archive
(
LPCWSTR
path
)
static
LPWSTR
msi_read_text_archive
(
LPCWSTR
path
,
DWORD
*
len
)
{
{
HANDLE
file
;
HANDLE
file
;
LPSTR
data
=
NULL
;
LPSTR
data
=
NULL
;
...
@@ -521,15 +521,17 @@ static LPWSTR msi_read_text_archive(LPCWSTR path)
...
@@ -521,15 +521,17 @@ static LPWSTR msi_read_text_archive(LPCWSTR path)
return
NULL
;
return
NULL
;
size
=
GetFileSize
(
file
,
NULL
);
size
=
GetFileSize
(
file
,
NULL
);
data
=
msi_alloc
(
size
+
1
);
if
(
!
(
data
=
msi_alloc
(
size
)))
goto
done
;
if
(
!
data
)
goto
done
;
if
(
!
ReadFile
(
file
,
data
,
size
,
&
read
,
NULL
))
if
(
!
ReadFile
(
file
,
data
,
size
,
&
read
,
NULL
)
||
read
!=
size
)
goto
done
;
goto
done
;
data
[
size
]
=
'\0'
;
while
(
!
data
[
size
-
1
])
size
--
;
wdata
=
strdupAtoW
(
data
);
*
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
data
,
size
,
NULL
,
0
);
if
((
wdata
=
msi_alloc
(
(
*
len
+
1
)
*
sizeof
(
WCHAR
)
)))
{
MultiByteToWideChar
(
CP_ACP
,
0
,
data
,
size
,
wdata
,
*
len
);
wdata
[
*
len
]
=
0
;
}
done:
done:
CloseHandle
(
file
);
CloseHandle
(
file
);
...
@@ -537,21 +539,22 @@ done:
...
@@ -537,21 +539,22 @@ done:
return
wdata
;
return
wdata
;
}
}
static
void
msi_parse_line
(
LPWSTR
*
line
,
LPWSTR
**
entries
,
DWORD
*
num_entries
)
static
void
msi_parse_line
(
LPWSTR
*
line
,
LPWSTR
**
entries
,
DWORD
*
num_entries
,
DWORD
*
len
)
{
{
LPWSTR
ptr
=
*
line
,
save
;
LPWSTR
ptr
=
*
line
,
save
;
DWORD
i
,
count
=
1
;
DWORD
i
,
count
=
1
,
chars_left
=
*
len
;
*
entries
=
NULL
;
*
entries
=
NULL
;
/* stay on this line */
/* stay on this line */
while
(
*
ptr
&&
*
ptr
!=
'\n'
)
while
(
chars_left
&&
*
ptr
!=
'\n'
)
{
{
/* entries are separated by tabs */
/* entries are separated by tabs */
if
(
*
ptr
==
'\t'
)
if
(
*
ptr
==
'\t'
)
count
++
;
count
++
;
ptr
++
;
ptr
++
;
chars_left
--
;
}
}
*
entries
=
msi_alloc
(
count
*
sizeof
(
LPWSTR
));
*
entries
=
msi_alloc
(
count
*
sizeof
(
LPWSTR
));
...
@@ -559,28 +562,43 @@ static void msi_parse_line(LPWSTR *line, LPWSTR **entries, DWORD *num_entries)
...
@@ -559,28 +562,43 @@ static void msi_parse_line(LPWSTR *line, LPWSTR **entries, DWORD *num_entries)
return
;
return
;
/* store pointers into the data */
/* store pointers into the data */
chars_left
=
*
len
;
for
(
i
=
0
,
ptr
=
*
line
;
i
<
count
;
i
++
)
for
(
i
=
0
,
ptr
=
*
line
;
i
<
count
;
i
++
)
{
{
while
(
*
ptr
&&
*
ptr
==
'\r'
)
ptr
++
;
while
(
chars_left
&&
*
ptr
==
'\r'
)
{
ptr
++
;
chars_left
--
;
}
save
=
ptr
;
save
=
ptr
;
while
(
*
ptr
&&
*
ptr
!=
'\t'
&&
*
ptr
!=
'\n'
&&
*
ptr
!=
'\r'
)
ptr
++
;
while
(
chars_left
&&
*
ptr
!=
'\t'
&&
*
ptr
!=
'\n'
&&
*
ptr
!=
'\r'
)
{
if
(
!*
ptr
)
*
ptr
=
'\n'
;
/* convert embedded nulls to \n */
ptr
++
;
chars_left
--
;
}
/* NULL-separate the data */
/* NULL-separate the data */
if
(
*
ptr
==
'\n'
||
*
ptr
==
'\r'
)
if
(
*
ptr
==
'\n'
||
*
ptr
==
'\r'
)
{
{
while
(
*
ptr
==
'\n'
||
*
ptr
==
'\r'
)
while
(
chars_left
&&
(
*
ptr
==
'\n'
||
*
ptr
==
'\r'
))
*
(
ptr
++
)
=
'\0'
;
{
*
(
ptr
++
)
=
0
;
chars_left
--
;
}
}
}
else
if
(
*
ptr
)
else
if
(
*
ptr
)
*
ptr
++
=
'\0'
;
{
*
(
ptr
++
)
=
0
;
chars_left
--
;
}
(
*
entries
)[
i
]
=
save
;
(
*
entries
)[
i
]
=
save
;
}
}
/* move to the next line if there's more, else EOF */
/* move to the next line if there's more, else EOF */
*
line
=
ptr
;
*
line
=
ptr
;
*
len
=
chars_left
;
if
(
num_entries
)
if
(
num_entries
)
*
num_entries
=
count
;
*
num_entries
=
count
;
}
}
...
@@ -916,12 +934,12 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
...
@@ -916,12 +934,12 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
lstrcatW
(
path
,
szBackSlash
);
lstrcatW
(
path
,
szBackSlash
);
lstrcatW
(
path
,
file
);
lstrcatW
(
path
,
file
);
data
=
msi_read_text_archive
(
path
);
data
=
msi_read_text_archive
(
path
,
&
len
);
ptr
=
data
;
ptr
=
data
;
msi_parse_line
(
&
ptr
,
&
columns
,
&
num_columns
);
msi_parse_line
(
&
ptr
,
&
columns
,
&
num_columns
,
&
len
);
msi_parse_line
(
&
ptr
,
&
types
,
&
num_types
);
msi_parse_line
(
&
ptr
,
&
types
,
&
num_types
,
&
len
);
msi_parse_line
(
&
ptr
,
&
labels
,
&
num_labels
);
msi_parse_line
(
&
ptr
,
&
labels
,
&
num_labels
,
&
len
);
if
(
num_columns
==
1
&&
!
columns
[
0
][
0
]
&&
num_labels
==
1
&&
!
labels
[
0
][
0
]
&&
if
(
num_columns
==
1
&&
!
columns
[
0
][
0
]
&&
num_labels
==
1
&&
!
labels
[
0
][
0
]
&&
num_types
==
2
&&
!
strcmpW
(
types
[
1
],
forcecodepage
))
num_types
==
2
&&
!
strcmpW
(
types
[
1
],
forcecodepage
))
...
@@ -944,9 +962,9 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
...
@@ -944,9 +962,9 @@ static UINT MSI_DatabaseImport(MSIDATABASE *db, LPCWSTR folder, LPCWSTR file)
}
}
/* read in the table records */
/* read in the table records */
while
(
*
ptr
)
while
(
len
)
{
{
msi_parse_line
(
&
ptr
,
&
records
[
num_records
],
NULL
);
msi_parse_line
(
&
ptr
,
&
records
[
num_records
],
NULL
,
&
len
);
num_records
++
;
num_records
++
;
temp_records
=
msi_realloc
(
records
,
(
num_records
+
1
)
*
sizeof
(
LPWSTR
*
));
temp_records
=
msi_realloc
(
records
,
(
num_records
+
1
)
*
sizeof
(
LPWSTR
*
));
...
...
dlls/msi/tests/db.c
View file @
e2ba5dce
...
@@ -9253,6 +9253,39 @@ static void test_createtable(void)
...
@@ -9253,6 +9253,39 @@ static void test_createtable(void)
DeleteFileA
(
msifile
);
DeleteFileA
(
msifile
);
}
}
static
void
test_embedded_nulls
(
void
)
{
static
const
char
control_table
[]
=
"Dialog
\t
Text
\n
"
"s72
\t
L0
\n
"
"Control
\t
Dialog
\n
"
"LicenseAgreementDlg
\t
text
\0
text"
;
UINT
r
,
sz
;
MSIHANDLE
hdb
,
hrec
;
char
buffer
[
32
];
r
=
MsiOpenDatabaseA
(
msifile
,
MSIDBOPEN_CREATE
,
&
hdb
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to open database %u
\n
"
,
r
);
GetCurrentDirectoryA
(
MAX_PATH
,
CURR_DIR
);
write_file
(
"temp_file"
,
control_table
,
sizeof
(
control_table
)
);
r
=
MsiDatabaseImportA
(
hdb
,
CURR_DIR
,
"temp_file"
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to import table %u
\n
"
,
r
);
DeleteFileA
(
"temp_file"
);
r
=
do_query
(
hdb
,
"SELECT `Text` FROM `Control` WHERE `Dialog` = 'LicenseAgreementDlg'"
,
&
hrec
);
ok
(
r
==
ERROR_SUCCESS
,
"query failed %u
\n
"
,
r
);
buffer
[
0
]
=
0
;
sz
=
sizeof
(
buffer
);
r
=
MsiRecordGetStringA
(
hrec
,
1
,
buffer
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to get string %u
\n
"
,
r
);
ok
(
!
memcmp
(
"text
\n
text"
,
buffer
,
sizeof
(
"text
\n
text"
)
-
1
),
"wrong buffer contents
\"
%s
\"\n
"
,
buffer
);
MsiCloseHandle
(
hrec
);
MsiCloseHandle
(
hdb
);
DeleteFileA
(
msifile
);
}
START_TEST
(
db
)
START_TEST
(
db
)
{
{
...
@@ -9307,4 +9340,5 @@ START_TEST(db)
...
@@ -9307,4 +9340,5 @@ START_TEST(db)
test_suminfo_import
();
test_suminfo_import
();
test_createtable
();
test_createtable
();
test_collation
();
test_collation
();
test_embedded_nulls
();
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment