- Implement RtlpDidUnicodeToOemWork to check for unmapped characters. Based on a patch by Daniel Zimmerman.

See issue #4548 for more details.

svn path=/trunk/; revision=43363
This commit is contained in:
Aleksey Bragin 2009-10-10 13:22:41 +00:00
parent 1ac07cde09
commit fcd17ff4fb
2 changed files with 59 additions and 4 deletions

View file

@ -33,6 +33,10 @@ PCHAR NlsUnicodeToOemTable =NULL;
PWCHAR NlsDbcsUnicodeToOemTable = NULL; PWCHAR NlsDbcsUnicodeToOemTable = NULL;
PUSHORT _NlsOemLeadByteInfo = NULL; /* exported */ PUSHORT _NlsOemLeadByteInfo = NULL; /* exported */
USHORT NlsOemDefaultChar = '\0';
USHORT NlsUnicodeDefaultChar = 0;
#define NlsOemLeadByteInfo _NlsOemLeadByteInfo #define NlsOemLeadByteInfo _NlsOemLeadByteInfo
#define INIT_FUNCTION #define INIT_FUNCTION
@ -435,6 +439,10 @@ RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
/* Set Unicode case map data */ /* Set Unicode case map data */
NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable; NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable;
NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable; NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable;
/* set the default characters for RtlpDidUnicodeToOemWork */
NlsOemDefaultChar = NlsTable->OemTableInfo.DefaultChar;
NlsUnicodeDefaultChar = NlsTable->OemTableInfo.TransDefaultChar;
} }

View file

@ -23,6 +23,9 @@ extern BOOLEAN NlsMbCodePageTag;
extern BOOLEAN NlsMbOemCodePageTag; extern BOOLEAN NlsMbOemCodePageTag;
extern PUSHORT NlsLeadByteInfo; extern PUSHORT NlsLeadByteInfo;
extern USHORT NlsOemDefaultChar;
extern USHORT NlsUnicodeDefaultChar;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* /*
@ -395,6 +398,45 @@ RtlFreeUnicodeString(IN PUNICODE_STRING UnicodeString)
} }
} }
/*
* @implemented
*
* NOTES
* Check the oem-string to match the uincoded-string.
*
* Functions who convert unicode strings to oem strings will set a DefaultChar from
* the OemCodepage when the character are unknown. So check it against the unicode string
* and return false when the unicode string not contain an TransDefaultChar.
*/
BOOLEAN
NTAPI
RtlpDidUnicodeToOemWork(IN PCUNICODE_STRING UnicodeString,
IN POEM_STRING OemString)
{
ULONG i = 0;
/* Go through all characters of a string */
while ((OemString->Buffer[i] != 0) &&
(i < OemString->Length))
{
/* Check if it got translated into '?', but source char
wasn't '?' equivalent */
if ((OemString->Buffer[i] == NlsOemDefaultChar) &&
(UnicodeString->Buffer[i] != NlsUnicodeDefaultChar))
{
/* Yes, it means unmappable characters were found */
return FALSE;
}
/* Move to the next char */
i++;
}
/* All chars were translated successfuly */
return TRUE;
}
/* /*
* @unimplemented * @unimplemented
*/ */
@ -1534,8 +1576,9 @@ RtlUnicodeStringToCountedOemString(
UniSource->Buffer, UniSource->Buffer,
UniSource->Length); UniSource->Length);
/* FIXME: Check if everything mapped correctly and /* Check for unmapped character */
* return STATUS_UNMAPPABLE_CHARACTER */ if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest))
Status = STATUS_UNMAPPABLE_CHARACTER;
if (!NT_SUCCESS(Status) && AllocateDestinationString) if (!NT_SUCCESS(Status) && AllocateDestinationString)
{ {
@ -1763,7 +1806,9 @@ RtlUpcaseUnicodeStringToCountedOemString(
UniSource->Buffer, UniSource->Buffer,
UniSource->Length); UniSource->Length);
/* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ /* Check for unmapped characters */
if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest))
Status = STATUS_UNMAPPABLE_CHARACTER;
if (!NT_SUCCESS(Status) && AllocateDestinationString) if (!NT_SUCCESS(Status) && AllocateDestinationString)
{ {
@ -1816,7 +1861,9 @@ RtlUpcaseUnicodeStringToOemString (
UniSource->Buffer, UniSource->Buffer,
UniSource->Length); UniSource->Length);
/* FIXME: Special check needed and return STATUS_UNMAPPABLE_CHARACTER */ /* Check for unmapped characters */
if (NT_SUCCESS(Status) && !RtlpDidUnicodeToOemWork(UniSource, OemDest))
Status = STATUS_UNMAPPABLE_CHARACTER;
if (!NT_SUCCESS(Status) && AllocateDestinationString) if (!NT_SUCCESS(Status) && AllocateDestinationString)
{ {