1 /******************************************************************************
2  *
3  * Module Name: aslascii - ASCII detection and support routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "aslcompiler.h"
45 #include <acapps.h>
46 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("aslascii")
49 
50 
51 /* Local prototypes */
52 
53 static void
54 FlConsumeAnsiComment (
55     FILE                    *Handle,
56     ASL_FILE_STATUS         *Status);
57 
58 static void
59 FlConsumeNewComment (
60     FILE                    *Handle,
61     ASL_FILE_STATUS         *Status);
62 
63 
64 /*******************************************************************************
65  *
66  * FUNCTION:    FlCheckForAcpiTable
67  *
68  * PARAMETERS:  Handle              - Open input file
69  *
70  * RETURN:      Status
71  *
72  * DESCRIPTION: Determine if a file seems to be a binary ACPI table, via the
73  *              following checks on what would be the table header:
74  *              0) File must be at least as long as an ACPI_TABLE_HEADER
75  *              1) The header length field must match the file size
76  *              2) Signature, OemId, OemTableId, AslCompilerId must be ASCII
77  *
78  ******************************************************************************/
79 
80 ACPI_STATUS
81 FlCheckForAcpiTable (
82     FILE                    *Handle)
83 {
84     ACPI_TABLE_HEADER       Table;
85     UINT32                  FileSize;
86     size_t                  Actual;
87     UINT32                  i;
88 
89 
90     /* Read a potential table header */
91 
92     Actual = fread (&Table, 1, sizeof (ACPI_TABLE_HEADER), Handle);
93     fseek (Handle, 0, SEEK_SET);
94 
95     if (Actual < sizeof (ACPI_TABLE_HEADER))
96     {
97         return (AE_ERROR);
98     }
99 
100     /* Header length field must match the file size */
101 
102     FileSize = CmGetFileSize (Handle);
103     if (Table.Length != FileSize)
104     {
105         return (AE_ERROR);
106     }
107 
108     /*
109      * These fields must be ASCII:
110      * Signature, OemId, OemTableId, AslCompilerId.
111      * We allow a NULL terminator in OemId and OemTableId.
112      */
113     for (i = 0; i < ACPI_NAME_SIZE; i++)
114     {
115         if (!ACPI_IS_ASCII ((UINT8) Table.Signature[i]))
116         {
117             return (AE_ERROR);
118         }
119 
120         if (!ACPI_IS_ASCII ((UINT8) Table.AslCompilerId[i]))
121         {
122             return (AE_ERROR);
123         }
124     }
125 
126     for (i = 0; (i < ACPI_OEM_ID_SIZE) && (Table.OemId[i]); i++)
127     {
128         if (!ACPI_IS_ASCII ((UINT8) Table.OemId[i]))
129         {
130             return (AE_ERROR);
131         }
132     }
133 
134     for (i = 0; (i < ACPI_OEM_TABLE_ID_SIZE) && (Table.OemTableId[i]); i++)
135     {
136         if (!ACPI_IS_ASCII ((UINT8) Table.OemTableId[i]))
137         {
138             return (AE_ERROR);
139         }
140     }
141 
142     printf ("Binary file appears to be a valid ACPI table, disassembling\n");
143     return (AE_OK);
144 }
145 
146 
147 /*******************************************************************************
148  *
149  * FUNCTION:    FlCheckForAscii
150  *
151  * PARAMETERS:  Handle              - Open input file
152  *              Filename            - Input filename
153  *              DisplayErrors       - TRUE if error messages desired
154  *
155  * RETURN:      Status
156  *
157  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
158  *              within comments. Note: does not handle nested comments and does
159  *              not handle comment delimiters within string literals. However,
160  *              on the rare chance this happens and an invalid character is
161  *              missed, the parser will catch the error by failing in some
162  *              spectactular manner.
163  *
164  ******************************************************************************/
165 
166 ACPI_STATUS
167 FlCheckForAscii (
168     FILE                    *Handle,
169     char                    *Filename,
170     BOOLEAN                 DisplayErrors)
171 {
172     UINT8                   Byte;
173     ACPI_SIZE               BadBytes = 0;
174     BOOLEAN                 OpeningComment = FALSE;
175     ASL_FILE_STATUS         Status;
176 
177 
178     Status.Line = 1;
179     Status.Offset = 0;
180 
181     /* Read the entire file */
182 
183     while (fread (&Byte, 1, 1, Handle) == 1)
184     {
185         /* Ignore comment fields (allow non-ascii within) */
186 
187         if (OpeningComment)
188         {
189             /* Check for second comment open delimiter */
190 
191             if (Byte == '*')
192             {
193                 FlConsumeAnsiComment (Handle, &Status);
194             }
195 
196             if (Byte == '/')
197             {
198                 FlConsumeNewComment (Handle, &Status);
199             }
200 
201             /* Reset */
202 
203             OpeningComment = FALSE;
204         }
205         else if (Byte == '/')
206         {
207             OpeningComment = TRUE;
208         }
209 
210         /* Check for an ASCII character */
211 
212         if (!ACPI_IS_ASCII (Byte))
213         {
214             if ((BadBytes < 10) && (DisplayErrors))
215             {
216                 AcpiOsPrintf (
217                     "Non-ASCII character [0x%2.2X] found in line %u, file offset 0x%.2X\n",
218                     Byte, Status.Line, Status.Offset);
219             }
220 
221             BadBytes++;
222         }
223 
224         /* Update line counter */
225 
226         else if (Byte == 0x0A)
227         {
228             Status.Line++;
229         }
230 
231         Status.Offset++;
232     }
233 
234     /* Seek back to the beginning of the source file */
235 
236     fseek (Handle, 0, SEEK_SET);
237 
238     /* Were there any non-ASCII characters in the file? */
239 
240     if (BadBytes)
241     {
242         if (DisplayErrors)
243         {
244             AcpiOsPrintf (
245                 "%u non-ASCII characters found in input source text, could be a binary file\n",
246                 BadBytes);
247             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
248         }
249 
250         return (AE_BAD_CHARACTER);
251     }
252 
253     /* File is OK (100% ASCII) */
254 
255     return (AE_OK);
256 }
257 
258 
259 /*******************************************************************************
260  *
261  * FUNCTION:    FlConsumeAnsiComment
262  *
263  * PARAMETERS:  Handle              - Open input file
264  *              Status              - File current status struct
265  *
266  * RETURN:      Number of lines consumed
267  *
268  * DESCRIPTION: Step over a normal slash-star type comment
269  *
270  ******************************************************************************/
271 
272 static void
273 FlConsumeAnsiComment (
274     FILE                    *Handle,
275     ASL_FILE_STATUS         *Status)
276 {
277     UINT8                   Byte;
278     BOOLEAN                 ClosingComment = FALSE;
279 
280 
281     while (fread (&Byte, 1, 1, Handle) == 1)
282     {
283         /* Scan until comment close is found */
284 
285         if (ClosingComment)
286         {
287             if (Byte == '/')
288             {
289                 return;
290             }
291 
292             if (Byte != '*')
293             {
294                 /* Reset */
295 
296                 ClosingComment = FALSE;
297             }
298         }
299         else if (Byte == '*')
300         {
301             ClosingComment = TRUE;
302         }
303 
304         /* Maintain line count */
305 
306         if (Byte == 0x0A)
307         {
308             Status->Line++;
309         }
310 
311         Status->Offset++;
312     }
313 }
314 
315 
316 /*******************************************************************************
317  *
318  * FUNCTION:    FlConsumeNewComment
319  *
320  * PARAMETERS:  Handle              - Open input file
321  *              Status              - File current status struct
322  *
323  * RETURN:      Number of lines consumed
324  *
325  * DESCRIPTION: Step over a slash-slash type of comment
326  *
327  ******************************************************************************/
328 
329 static void
330 FlConsumeNewComment (
331     FILE                    *Handle,
332     ASL_FILE_STATUS         *Status)
333 {
334     UINT8                   Byte;
335 
336 
337     while (fread (&Byte, 1, 1, Handle) == 1)
338     {
339         Status->Offset++;
340 
341         /* Comment ends at newline */
342 
343         if (Byte == 0x0A)
344         {
345             Status->Line++;
346             return;
347         }
348     }
349 }
350