1 /******************************************************************************
2  *
3  * Module Name: aslascii - ASCII detection and support routines
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, 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 <actables.h>
46 #include <acapps.h>
47 
48 #define _COMPONENT          ACPI_COMPILER
49         ACPI_MODULE_NAME    ("aslascii")
50 
51 
52 /* Local prototypes */
53 
54 static void
55 FlConsumeAnsiComment (
56     FILE                    *Handle,
57     ASL_FILE_STATUS         *Status);
58 
59 static void
60 FlConsumeNewComment (
61     FILE                    *Handle,
62     ASL_FILE_STATUS         *Status);
63 
64 
65 /*******************************************************************************
66  *
67  * FUNCTION:    FlIsFileAsciiSource
68  *
69  * PARAMETERS:  Filename            - Full input filename
70  *              DisplayErrors       - TRUE if error messages desired
71  *
72  * RETURN:      Status
73  *
74  * DESCRIPTION: Verify that the input file is entirely ASCII. Ignores characters
75  *              within comments. Note: does not handle nested comments and does
76  *              not handle comment delimiters within string literals. However,
77  *              on the rare chance this happens and an invalid character is
78  *              missed, the parser will catch the error by failing in some
79  *              spectactular manner.
80  *
81  ******************************************************************************/
82 
83 ACPI_STATUS
84 FlIsFileAsciiSource (
85     char                    *Filename,
86     BOOLEAN                 DisplayErrors)
87 {
88     UINT8                   Byte;
89     ACPI_SIZE               BadBytes = 0;
90     BOOLEAN                 OpeningComment = FALSE;
91     ASL_FILE_STATUS         Status;
92     FILE                    *Handle;
93 
94 
95     /* Open file in text mode so file offset is always accurate */
96 
97     Handle = fopen (Filename, "rb");
98     if (!Handle)
99     {
100         perror ("Could not open input file");
101         return (AE_ERROR);
102     }
103 
104     Status.Line = 1;
105     Status.Offset = 0;
106 
107     /* Read the entire file */
108 
109     while (fread (&Byte, 1, 1, Handle) == 1)
110     {
111         /* Ignore comment fields (allow non-ascii within) */
112 
113         if (OpeningComment)
114         {
115             /* Check for second comment open delimiter */
116 
117             if (Byte == '*')
118             {
119                 FlConsumeAnsiComment (Handle, &Status);
120             }
121 
122             if (Byte == '/')
123             {
124                 FlConsumeNewComment (Handle, &Status);
125             }
126 
127             /* Reset */
128 
129             OpeningComment = FALSE;
130         }
131         else if (Byte == '/')
132         {
133             OpeningComment = TRUE;
134         }
135 
136         /* Check for an ASCII character */
137 
138         if (!ACPI_IS_ASCII (Byte))
139         {
140             if ((BadBytes < 10) && (DisplayErrors))
141             {
142                 AcpiOsPrintf (
143                     "Found non-ASCII character in source text: "
144                     "0x%2.2X in line %u, file offset 0x%2.2X\n",
145                     Byte, Status.Line, Status.Offset);
146             }
147             BadBytes++;
148         }
149 
150         /* Ensure character is either printable or a "space" char */
151 
152         else if (!isprint (Byte) && !isspace (Byte))
153         {
154             if ((BadBytes < 10) && (DisplayErrors))
155             {
156                 AcpiOsPrintf (
157                     "Found invalid character in source text: "
158                     "0x%2.2X in line %u, file offset 0x%2.2X\n",
159                     Byte, Status.Line, Status.Offset);
160             }
161             BadBytes++;
162         }
163 
164         /* Update line counter as necessary */
165 
166         if (Byte == 0x0A)
167         {
168             Status.Line++;
169         }
170 
171         Status.Offset++;
172     }
173 
174     fclose (Handle);
175 
176     /* Were there any non-ASCII characters in the file? */
177 
178     if (BadBytes)
179     {
180         if (DisplayErrors)
181         {
182             AcpiOsPrintf (
183                 "Total %u invalid characters found in input source text, "
184                 "could be a binary file\n", BadBytes);
185             AslError (ASL_ERROR, ASL_MSG_NON_ASCII, NULL, Filename);
186         }
187 
188         return (AE_BAD_CHARACTER);
189     }
190 
191     /* File is OK (100% ASCII) */
192 
193     return (AE_OK);
194 }
195 
196 
197 /*******************************************************************************
198  *
199  * FUNCTION:    FlConsumeAnsiComment
200  *
201  * PARAMETERS:  Handle              - Open input file
202  *              Status              - File current status struct
203  *
204  * RETURN:      Number of lines consumed
205  *
206  * DESCRIPTION: Step over a normal slash-star type comment
207  *
208  ******************************************************************************/
209 
210 static void
211 FlConsumeAnsiComment (
212     FILE                    *Handle,
213     ASL_FILE_STATUS         *Status)
214 {
215     UINT8                   Byte;
216     BOOLEAN                 ClosingComment = FALSE;
217 
218 
219     while (fread (&Byte, 1, 1, Handle) == 1)
220     {
221         /* Scan until comment close is found */
222 
223         if (ClosingComment)
224         {
225             if (Byte == '/')
226             {
227                 Status->Offset++;
228                 return;
229             }
230 
231             if (Byte != '*')
232             {
233                 /* Reset */
234 
235                 ClosingComment = FALSE;
236             }
237         }
238         else if (Byte == '*')
239         {
240             ClosingComment = TRUE;
241         }
242 
243         /* Maintain line count */
244 
245         if (Byte == 0x0A)
246         {
247             Status->Line++;
248         }
249 
250         Status->Offset++;
251     }
252 }
253 
254 
255 /*******************************************************************************
256  *
257  * FUNCTION:    FlConsumeNewComment
258  *
259  * PARAMETERS:  Handle              - Open input file
260  *              Status              - File current status struct
261  *
262  * RETURN:      Number of lines consumed
263  *
264  * DESCRIPTION: Step over a slash-slash type of comment
265  *
266  ******************************************************************************/
267 
268 static void
269 FlConsumeNewComment (
270     FILE                    *Handle,
271     ASL_FILE_STATUS         *Status)
272 {
273     UINT8                   Byte;
274 
275 
276     while (fread (&Byte, 1, 1, Handle) == 1)
277     {
278         Status->Offset++;
279 
280         /* Comment ends at newline */
281 
282         if (Byte == 0x0A)
283         {
284             Status->Line++;
285             return;
286         }
287     }
288 }
289