Skip to content

Commit e62b7a7

Browse files
author
Josh Peterson
committed
[TermInfo] support new file format terminfo2 introduced with ncurses6.1
These changes are applied from upstream Mono at mono@e25f5c3. They correct an exception that happens on Linux like this: ``` System.TypeInitializationException: The type initializer for 'System.Console' threw an exception. ---> System.TypeInitializationException: The type initializer for 'System.ConsoleDriver' threw an exception. ---> System.Exception: Magic number is wrong: 542 at System.TermInfoReader.ReadHeader (System.Byte[] buffer, System.Int32& position) [0x0008d] in /Users/bokken/build/output/Unity-Technologies/mono/mcs/class/corlib/System/TermInfoReader.cs:134 at System.TermInfoReader..ctor (System.String term, System.String filename) [0x0005f] in /Users/bokken/build/output/Unity-Technologies/mono/mcs/class/corlib/System/TermInfoReader.cs:97 at System.TermInfoDriver..ctor (System.String term) [0x00055] in /Users/bokken/build/output/Unity-Technologies/mono/mcs/class/corlib/System/TermInfoDriver.cs:164 at System.ConsoleDriver.CreateTermInfoDriver (System.String term) [0x00000] in /Users/bokken/build/output/Unity-Technologies/mono/mcs/class/corlib/System/ConsoleDriver.cs:73 at System.ConsoleDriver..cctor () [0x0004d] in /Users/bokken/build/output/Unity-Technologies/mono/mcs/class/corlib/System/ConsoleDriver.cs:57 ```
1 parent f73f80f commit e62b7a7

File tree

1 file changed

+48
-17
lines changed

1 file changed

+48
-17
lines changed

mcs/class/corlib/System/TermInfoReader.cs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
using System.Text;
3333
namespace System {
3434
// This class reads data from a byte array or file containing the terminfo capabilities
35-
// information for any given terminal. The maximum allowed size is 4096 bytes.
35+
// information for any given terminal. The maximum allowed size is 4096 (or
36+
// 32768 for terminfo2) bytes.
3637
//
3738
// Terminfo database files are divided in the following sections:
3839
//
@@ -45,7 +46,7 @@ namespace System {
4546
//
4647
// The header is as follows:
4748
//
48-
// Magic number (0x1 and 0x1A)
49+
// Magic number (0x11A/0432 or 0x21e/01036 for terminfo2)
4950
// Terminal names size
5051
// Boolean section size
5152
// Numeric section size
@@ -58,8 +59,9 @@ namespace System {
5859
// The boolean capabilities section has bytes that are set to 1 if the capability is supported
5960
// and 0 otherwise. If the index of a capability is greater than the section size, 0 is assumed.
6061
//
61-
// The numeric capabilities section holds 2-byte integers in little endian format. No negative
62-
// values are allowed and the absence of a capability is marked as two 0xFF.
62+
// The numeric capabilities section holds 2-byte integers (4-byte integers for terminfo2) in
63+
// little endian format. No negative values are allowed and the absence of a capability is marked
64+
// as two 0xFF (four 0xFF for terminfo2).
6365
//
6466
// The string offsets section contains 2-byte integer offsets into the string capabilies section.
6567
// If the capability is not supported, the index will be two 0xFF bytes.
@@ -72,17 +74,17 @@ namespace System {
7274
//
7375

7476
class TermInfoReader {
75-
//short nameSize;
76-
short boolSize;
77-
short numSize;
78-
short strOffsets;
79-
//short strSize;
77+
int boolSize;
78+
int numSize;
79+
int strOffsets;
8080

8181
//string [] names; // Last one is the description
8282
byte [] buffer;
8383
int booleansOffset;
8484
//string term;
8585

86+
int intOffset;
87+
8688
public TermInfoReader (string term, string filename)
8789
{
8890
using (FileStream st = File.OpenRead (filename)) {
@@ -114,12 +116,21 @@ public TermInfoReader (string term, byte [] buffer)
114116
// get { return term; }
115117
// }
116118

119+
void DetermineVersion (short magic)
120+
{
121+
if (magic == 0x11a)
122+
intOffset = 2;
123+
else if (magic == 0x21e)
124+
intOffset = 4;
125+
else
126+
throw new Exception (String.Format ("Magic number is wrong: {0}", magic));
127+
}
128+
117129
void ReadHeader (byte [] buffer, ref int position)
118130
{
119131
short magic = GetInt16 (buffer, position);
120132
position += 2;
121-
if (magic != 282)
122-
throw new Exception (String.Format ("Magic number is wrong: {0}", magic));
133+
DetermineVersion (magic);
123134

124135
/*nameSize =*/ GetInt16 (buffer, position);
125136
position += 2;
@@ -161,8 +172,8 @@ public int Get (TermInfoNumbers number)
161172
if ((offset % 2) == 1)
162173
offset++;
163174

164-
offset += ((int) number) * 2;
165-
return GetInt16 (buffer, offset);
175+
offset += ((int) number) * intOffset;
176+
return GetInteger (buffer, offset);
166177
}
167178

168179
public string Get (TermInfoStrings tstr)
@@ -175,7 +186,7 @@ public string Get (TermInfoStrings tstr)
175186
if ((offset % 2) == 1)
176187
offset++;
177188

178-
offset += numSize * 2;
189+
offset += numSize * intOffset;
179190
int off2 = GetInt16 (buffer, offset + (int) tstr * 2);
180191
if (off2 == -1)
181192
return null;
@@ -193,7 +204,7 @@ public byte [] GetStringBytes (TermInfoStrings tstr)
193204
if ((offset % 2) == 1)
194205
offset++;
195206

196-
offset += numSize * 2;
207+
offset += numSize * intOffset;
197208
int off2 = GetInt16 (buffer, offset + (int) tstr * 2);
198209
if (off2 == -1)
199210
return null;
@@ -211,6 +222,27 @@ short GetInt16 (byte [] buffer, int offset)
211222
return (short) (uno + dos * 256);
212223
}
213224

225+
int GetInt32 (byte [] buffer, int offset)
226+
{
227+
int b1 = (int) buffer [offset];
228+
int b2 = (int) buffer [offset + 1];
229+
int b3 = (int) buffer [offset + 2];
230+
int b4 = (int) buffer [offset + 3];
231+
if (b1 == 255 && b2 == 255 && b3 == 255 && b4 == 255)
232+
return -1;
233+
234+
return b1 + b2 << 8 + b3 << 16 + b4 << 24;
235+
}
236+
237+
int GetInteger (byte [] buffer, int offset)
238+
{
239+
if (intOffset == 2)
240+
return GetInt16 (buffer, offset);
241+
else
242+
// intOffset == 4
243+
return GetInt32 (buffer, offset);
244+
}
245+
214246
string GetString (byte [] buffer, int offset)
215247
{
216248
int length = 0;
@@ -249,5 +281,4 @@ internal static string Escape (string s)
249281
}
250282
}
251283
}
252-
#endif
253-
284+
#endif

0 commit comments

Comments
 (0)