From aae02a43daf93e979f536514fde6172de6ba44ff Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Fri, 15 May 2020 11:31:40 +0200 Subject: [PATCH] Modified setting system and override character tables --- CONTRIBUTORS | 2 ++ HISTORY | 9 ++++++++- libsi/si.c | 50 ++++++++++++++++++++++++++++++-------------------- libsi/si.h | 6 ++++-- vdr.c | 6 +++--- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f085eeba..6df5f535 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3591,6 +3591,8 @@ Helmut Binder for adding the language code for Bulgarian for a patch that was used as a base for fixing handling multi part ExtendedEventDescriptors where only the first part contains information about the character table + for suggesting to check and report whether the given value is valid when setting the + override character table Ulrich Eckhardt for reporting a problem with shutdown after user inactivity in case a plugin is diff --git a/HISTORY b/HISTORY index fafad735..22c2bd16 100644 --- a/HISTORY +++ b/HISTORY @@ -9420,7 +9420,7 @@ Video Disk Recorder Revision History - Fixed handling the S2SatelliteDeliverySystemDescriptor for transponders broadcasting in "backwards compatibility mode" according to ETSI EN 300 468 (thanks to Onur Sentürk). -2020-05-14: +2020-05-15: - Fixed moving channels between number groups in SVDRP's MOVC command and the Channels menu, in case a channel is moved to a higher number and into a numbered group @@ -9434,3 +9434,10 @@ Video Disk Recorder Revision History - Added the language code for Bulgarian (thanks to Helmut Binder). - Fixed handling multi part ExtendedEventDescriptors where only the first part contains information about the character table (based on a patch from Helmut Binder). +- When setting the system character table, it is no longer checked against the known + entries that are hard coded in libsi/si.c, but rather given to iconv_open() and the + result of that call is used to check whether the given name is valid. +- Checking whether the system character table is "single byte" is now done by checking + the result of a sample call to iconv(). +- Setting the override character table now checks and reports whether the given value + is valid (suggested by Helmut Binder). diff --git a/libsi/si.c b/libsi/si.c index c294c2fc..e3d58cac 100644 --- a/libsi/si.c +++ b/libsi/si.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 4.1 2020/05/14 21:21:03 kls Exp $ + * $Id: si.c 4.2 2020/05/15 11:31:40 kls Exp $ * * ***************************************************************************/ @@ -311,7 +311,7 @@ static const char *CharacterTables2[] = { #define NumEntries(Table) (sizeof(Table) / sizeof(char *)) -static const char *SystemCharacterTable = NULL; +static char *SystemCharacterTable = NULL; bool SystemCharacterTableIsSingleByte = true; bool systemCharacterTableIsSingleByte(void) @@ -321,32 +321,42 @@ bool systemCharacterTableIsSingleByte(void) static char *OverrideCharacterTable = NULL; -void SetOverrideCharacterTable(const char *CharacterTable) +bool SetOverrideCharacterTable(const char *CharacterTable) { free(OverrideCharacterTable); OverrideCharacterTable = CharacterTable ? strdup(CharacterTable) : NULL; + if (OverrideCharacterTable) { + // Check whether the character table is known: + iconv_t cd = iconv_open(SystemCharacterTable, OverrideCharacterTable); + if (cd != (iconv_t)-1) { + iconv_close(cd); + return true; + } + } + return false; } bool SetSystemCharacterTable(const char *CharacterTable) { - if (CharacterTable) { - for (unsigned int i = 0; i < NumEntries(CharacterTables1); i++) { - if (CharacterTables1[i] && strcasecmp(CharacterTable, CharacterTables1[i]) == 0) { - SystemCharacterTable = CharacterTables1[i]; - SystemCharacterTableIsSingleByte = i <= SingleByteLimit; - return true; + free(SystemCharacterTable); + SystemCharacterTable = CharacterTable ? strdup(CharacterTable) : NULL; + SystemCharacterTableIsSingleByte = true; + if (SystemCharacterTable) { + // Check whether the character table is known and "single byte": + char a[] = "ä"; + char *pa = a; + char b[10]; + char *pb = b; + size_t la = strlen(a); + size_t lb = sizeof(b); + iconv_t cd = iconv_open(SystemCharacterTable, "ISO-8859-1"); + if (cd != (iconv_t)-1) { + if (iconv(cd, &pa, &la, &pb, &lb) != size_t(-1)) { + *pb = 0; + SystemCharacterTableIsSingleByte = strlen(b) == 1; } + iconv_close(cd); + return true; } - for (unsigned int i = 0; i < NumEntries(CharacterTables2); i++) { - if (CharacterTables2[i] && strcasecmp(CharacterTable, CharacterTables2[i]) == 0) { - SystemCharacterTable = CharacterTables2[i]; - SystemCharacterTableIsSingleByte = true; - return true; - } - } - } else { - SystemCharacterTable = NULL; - SystemCharacterTableIsSingleByte = true; - return true; } return false; } diff --git a/libsi/si.h b/libsi/si.h index c5f426ef..aae43f01 100644 --- a/libsi/si.h +++ b/libsi/si.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.h 4.1 2020/05/14 21:21:03 kls Exp $ + * $Id: si.h 4.2 2020/05/15 11:31:40 kls Exp $ * * ***************************************************************************/ @@ -527,7 +527,9 @@ protected: // Set the character table to use for strings that do not begin with a character // table indicator. Call with NULL to turn this off. -void SetOverrideCharacterTable(const char *CharacterTable); +// Must be called *after* SetSystemCharacterTable()! +// Returns true if the character table was recognized. +bool SetOverrideCharacterTable(const char *CharacterTable); // Call this function to set the system character table. CharacterTable is a string // like "iso8859-15" or "utf-8" (case insensitive). // Returns true if the character table was recognized. diff --git a/vdr.c b/vdr.c index 0002214e..77f65673 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 4.31 2020/05/07 10:45:41 kls Exp $ + * $Id: vdr.c 4.32 2020/05/15 11:31:40 kls Exp $ */ #include @@ -726,8 +726,8 @@ int main(int argc, char *argv[]) isyslog("use of environment variable VDR_CHARSET_OVERRIDE (%s) is deprecated!", DeprecatedVdrCharsetOverride); #endif if (OverrideCharacterTable) { - isyslog("override character table is '%s'", OverrideCharacterTable); - SI::SetOverrideCharacterTable(OverrideCharacterTable); + bool known = SI::SetOverrideCharacterTable(OverrideCharacterTable); + isyslog("override character table is '%s' - %s", OverrideCharacterTable, known ? "known" : "unknown"); } // Initialize internationalization: