From patchwork Sat Aug 7 07:14:37 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerry DeLisle X-Patchwork-Id: 61164 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 820AAB6EEC for ; Sat, 7 Aug 2010 17:15:10 +1000 (EST) Received: (qmail 13160 invoked by alias); 7 Aug 2010 07:15:02 -0000 Received: (qmail 13075 invoked by uid 22791); 7 Aug 2010 07:14:59 -0000 X-SWARE-Spam-Status: No, hits=1.6 required=5.0 tests=AWL, BAYES_00, BOTNET, RCVD_IN_DNSWL_NONE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from vms173001pub.verizon.net (HELO vms173001pub.verizon.net) (206.46.173.1) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 07 Aug 2010 07:14:53 +0000 Received: from [192.168.1.5] ([unknown] [71.115.233.80]) by vms173001.mailsrvcs.net (Sun Java(tm) System Messaging Server 7u2-7.02 32bit (built Apr 16 2009)) with ESMTPA id <0L6R00D1OTGDR760@vms173001.mailsrvcs.net>; Sat, 07 Aug 2010 02:14:39 -0500 (CDT) Message-id: <4C5D07DD.3060309@verizon.net> Date: Sat, 07 Aug 2010 00:14:37 -0700 From: Jerry DeLisle User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100713 Thunderbird/3.0.6 MIME-version: 1.0 To: gfortran Cc: gcc patches Subject: [patch, libgfortran] PR45143 Endless loop with unlimited edit descriptor Content-type: multipart/mixed; boundary=------------070602080600090107020701 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, The attached patch adds a check at run time for an unlimited format specifier without an associated data edit descriptor. A compile time check will be a separate patch. The moving of structure definitions to format.h is un-related to the patch. Seemed the correct place for it. Regression tested on i686-pc-linux-gnu. OK for trunk? Regards, Jerry 2010-08-06 Jerry DeLisle PR libfortran/45143 * io/format.c: Remove fnode storage structure definitions, moving these to format.h. (parse_format_list): Add check for data descriptors, taking care of nested formats. Adjust calling parameters to pass a check flag. (parse_format): Likewise. * io/format.h: Add structures moved from format.c. ! { dg-do run } ! PR45143 Endless loop with unlimited edit descriptor print 20, "1234", "abcd", "14rfa5" 20 format ( *('start',('ahdh',('dhdhhow',a),'ndlownd '))) print 30, "1234", "abcd", "14rfa5" 30 format ( *('start',('ahdh',('dhdhhow'),'ndlownd '))) end ! { dg-shouldfail "Fortran runtime error: '*' requires at least one associated data descriptor" } Index: format.c =================================================================== --- format.c (revision 162964) +++ format.c (working copy) @@ -35,29 +35,7 @@ see the files COPYING3 and COPYING.RUNTIME respect #include #include -#define FARRAY_SIZE 64 -typedef struct fnode_array -{ - struct fnode_array *next; - fnode array[FARRAY_SIZE]; -} -fnode_array; - -typedef struct format_data -{ - char *format_string, *string; - const char *error; - char error_element; - format_token saved_token; - int value, format_string_len, reversion_ok; - fnode *avail; - const fnode *saved_format; - fnode_array *last; - fnode_array array; -} -format_data; - static const fnode colon_node = { FMT_COLON, 0, NULL, NULL, {{ 0, 0, 0 }}, 0, NULL }; @@ -612,13 +590,13 @@ format_lex (format_data *fmt) * parenthesis node which contains the rest of the list. */ static fnode * -parse_format_list (st_parameter_dt *dtp, bool *save_ok) +parse_format_list (st_parameter_dt *dtp, bool *save_ok, bool *seen_dd) { fnode *head, *tail; format_token t, u, t2; int repeat; format_data *fmt = dtp->u.p.fmt; - bool saveit; + bool saveit, seen_data_desc = false; head = tail = NULL; saveit = *save_ok; @@ -638,10 +616,14 @@ static fnode * } get_fnode (fmt, &head, &tail, FMT_LPAREN); tail->repeat = -2; /* Signifies unlimited format. */ - tail->u.child = parse_format_list (dtp, &saveit); + tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc); if (fmt->error != NULL) goto finished; - + if (!seen_data_desc) + { + fmt->error = "'*' requires at least one associated data descriptor"; + goto finished; + } goto between_desc; case FMT_POSINT: @@ -653,7 +635,8 @@ static fnode * case FMT_LPAREN: get_fnode (fmt, &head, &tail, FMT_LPAREN); tail->repeat = repeat; - tail->u.child = parse_format_list (dtp, &saveit); + tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc); + *seen_dd = seen_data_desc; if (fmt->error != NULL) goto finished; @@ -680,7 +663,8 @@ static fnode * case FMT_LPAREN: get_fnode (fmt, &head, &tail, FMT_LPAREN); tail->repeat = 1; - tail->u.child = parse_format_list (dtp, &saveit); + tail->u.child = parse_format_list (dtp, &saveit, &seen_data_desc); + *seen_dd = seen_data_desc; if (fmt->error != NULL) goto finished; @@ -821,6 +805,7 @@ static fnode * case FMT_F: case FMT_G: repeat = 1; + *seen_dd = true; goto data_desc; case FMT_H: @@ -1217,7 +1202,7 @@ void parse_format (st_parameter_dt *dtp) { format_data *fmt; - bool format_cache_ok; + bool format_cache_ok, seen_data_desc = false; /* Don't cache for internal units and set an arbitrary limit on the size of format strings we will cache. (Avoids memory issues.) */ @@ -1266,7 +1251,8 @@ parse_format (st_parameter_dt *dtp) fmt->avail++; if (format_lex (fmt) == FMT_LPAREN) - fmt->array.array[0].u.child = parse_format_list (dtp, &format_cache_ok); + fmt->array.array[0].u.child = parse_format_list (dtp, &format_cache_ok, + &seen_data_desc); else fmt->error = "Missing initial left parenthesis in format"; Index: format.h =================================================================== --- format.h (revision 162964) +++ format.h (working copy) @@ -92,6 +92,32 @@ struct fnode }; +/* A storage structures for format node data. */ + +#define FARRAY_SIZE 64 + +typedef struct fnode_array +{ + struct fnode_array *next; + fnode array[FARRAY_SIZE]; +} +fnode_array; + + +typedef struct format_data +{ + char *format_string, *string; + const char *error; + char error_element; + format_token saved_token; + int value, format_string_len, reversion_ok; + fnode *avail; + const fnode *saved_format; + fnode_array *last; + fnode_array array; +} +format_data; + extern void parse_format (st_parameter_dt *); internal_proto(parse_format);