From d5a1fde397269bd60b99e70a4eb2934b75fd31ec Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 24 Jan 2019 16:46:55 -0500 Subject: [PATCH] Remove infinite-loop hazards in ecpg test suite. A report from Andrew Dunstan showed that an ecpglib breakage that causes repeated query failures could lead to infinite loops in some ecpg test scripts, because they contain "while(1)" loops with no exit condition other than successful test completion. That might be all right for manual testing, but it seems entirely unacceptable for automated test environments such as our buildfarm. We don't want buildfarm owners to have to intervene manually when a test goes wrong. To fix, just change all those while(1) loops to exit after at most 100 iterations (which is more than any of them expect to iterate). This seems sufficient since we'd see discrepancies in the test output if any loop executed the wrong number of times. I tested this by dint of intentionally breaking ecpg_do_prologue to always fail, and verifying that the tests still got to completion. Back-patch to all supported branches, since the whole point of this exercise is to protect the buildfarm against future mistakes. Discussion: https://postgr.es/m/18693.1548302004@sss.pgh.pa.us --- .../ecpg/test/compat_informix/test_informix.pgc | 4 ++-- src/interfaces/ecpg/test/compat_oracle/char_array.pgc | 4 ++-- .../ecpg/test/expected/compat_informix-test_informix.c | 4 ++-- .../ecpg/test/expected/compat_oracle-char_array.c | 4 ++-- .../ecpg/test/expected/pgtypeslib-nan_test.c | 10 +++++----- src/interfaces/ecpg/test/expected/preproc-autoprep.c | 2 +- src/interfaces/ecpg/test/expected/preproc-outofscope.c | 4 ++-- src/interfaces/ecpg/test/expected/preproc-variable.c | 4 ++-- .../ecpg/test/expected/preproc-whenever_do_continue.c | 7 +++++-- src/interfaces/ecpg/test/expected/sql-fetch.c | 8 ++++---- src/interfaces/ecpg/test/expected/sql-quote.c | 6 +++--- src/interfaces/ecpg/test/pgtypeslib/nan_test.pgc | 8 ++++---- src/interfaces/ecpg/test/preproc/autoprep.pgc | 2 +- src/interfaces/ecpg/test/preproc/outofscope.pgc | 4 ++-- src/interfaces/ecpg/test/preproc/variable.pgc | 4 ++-- .../ecpg/test/preproc/whenever_do_continue.pgc | 4 ++-- src/interfaces/ecpg/test/sql/fetch.pgc | 6 +++--- src/interfaces/ecpg/test/sql/quote.pgc | 4 ++-- 18 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/interfaces/ecpg/test/compat_informix/test_informix.pgc b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc index 8b7692b0fdd..82a7d45b768 100644 --- a/src/interfaces/ecpg/test/compat_informix/test_informix.pgc +++ b/src/interfaces/ecpg/test/compat_informix/test_informix.pgc @@ -11,7 +11,7 @@ static void dosqlprint(void) { int main(void) { - $int i = 14; + $int i = 14, loopcount; $decimal j, m, n; $string c[10]; @@ -52,7 +52,7 @@ int main(void) deccvint(0, &j); - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { $fetch forward c into :i, :j, :c; if (sqlca.sqlcode == 100) break; diff --git a/src/interfaces/ecpg/test/compat_oracle/char_array.pgc b/src/interfaces/ecpg/test/compat_oracle/char_array.pgc index 8d7d9bf2d19..7ee312216ca 100644 --- a/src/interfaces/ecpg/test/compat_oracle/char_array.pgc +++ b/src/interfaces/ecpg/test/compat_oracle/char_array.pgc @@ -19,7 +19,7 @@ int main() { EXEC SQL WHENEVER SQLERROR SQLPRINT; const char *ppppp = "XXXXX"; - + int loopcount; EXEC SQL BEGIN DECLARE SECTION; char shortstr[5]; char bigstr[11]; @@ -44,7 +44,7 @@ int main() { EXEC SQL WHENEVER NOT FOUND DO BREAK; printf("Full Str. : Short Ind.\n"); - while(1) { + for (loopcount = 0; loopcount < 100; loopcount++) { strncpy(shortstr, ppppp, sizeof shortstr); memset(bigstr, 0, sizeof bigstr); EXEC SQL FETCH C into :bigstr :bigstr_ind, :shortstr :shstr_ind; diff --git a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c index 99349475f87..64415344981 100644 --- a/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c +++ b/src/interfaces/ecpg/test/expected/compat_informix-test_informix.c @@ -33,7 +33,7 @@ int main(void) { #line 14 "test_informix.pgc" - int i = 14 ; + int i = 14 , loopcount ; #line 14 "test_informix.pgc" @@ -156,7 +156,7 @@ if (sqlca.sqlcode < 0) dosqlprint ( );} deccvint(0, &j); - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch forward c", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), diff --git a/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c b/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c index c9d2badb6a6..ee8624f0ec5 100644 --- a/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c +++ b/src/interfaces/ecpg/test/expected/compat_oracle-char_array.c @@ -41,7 +41,7 @@ int main() { const char *ppppp = "XXXXX"; - + int loopcount; /* exec sql begin declare section */ @@ -156,7 +156,7 @@ if (sqlca.sqlcode < 0) sqlprint();} printf("Full Str. : Short Ind.\n"); - while(1) { + for (loopcount = 0; loopcount < 100; loopcount++) { strncpy(shortstr, ppppp, sizeof shortstr); memset(bigstr, 0, sizeof bigstr); { ECPGdo(__LINE__, 3, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c index c8312840591..b7e80547950 100644 --- a/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c +++ b/src/interfaces/ecpg/test/expected/pgtypeslib-nan_test.c @@ -36,13 +36,13 @@ int main(void) { /* exec sql begin declare section */ - + #line 21 "nan_test.pgc" - int id ; + int id , loopcount ; #line 22 "nan_test.pgc" double d ; @@ -90,7 +90,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} if (sqlca.sqlcode < 0) sqlprint ( );} #line 36 "nan_test.pgc" - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -145,7 +145,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} if (sqlca.sqlcode < 0) sqlprint ( );} #line 52 "nan_test.pgc" - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), @@ -229,7 +229,7 @@ if (sqlca.sqlcode < 0) sqlprint ( );} if (sqlca.sqlcode < 0) sqlprint ( );} #line 78 "nan_test.pgc" - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch from cur1", ECPGt_EOIT, ECPGt_int,&(id),(long)1,(long)1,sizeof(int), diff --git a/src/interfaces/ecpg/test/expected/preproc-autoprep.c b/src/interfaces/ecpg/test/expected/preproc-autoprep.c index 10ede3ec627..8ed5a2ca2c1 100644 --- a/src/interfaces/ecpg/test/expected/preproc-autoprep.c +++ b/src/interfaces/ecpg/test/expected/preproc-autoprep.c @@ -197,7 +197,7 @@ if (sqlca.sqlcode < 0) sqlprint();} i = 0; - while (1) + while (i < 100) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur1", ECPGt_EOIT, ECPGt_int,&(item1),(long)1,(long)1,sizeof(int), diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c index b23107714c9..dc9cdbc909e 100644 --- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c +++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c @@ -267,7 +267,7 @@ main (void) { MYTYPE *myvar; MYNULLTYPE *mynullvar; - + int loopcount; char msg[128]; ECPGdebug(1, stderr); @@ -333,7 +333,7 @@ if (sqlca.sqlcode < 0) exit (1);} #line 96 "outofscope.pgc" - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { memset(myvar, 0, sizeof(MYTYPE)); get_record1(); diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c index 08e2355d169..3954f837690 100644 --- a/src/interfaces/ecpg/test/expected/preproc-variable.c +++ b/src/interfaces/ecpg/test/expected/preproc-variable.c @@ -120,7 +120,7 @@ main (void) #line 37 "variable.pgc" - + int loopcount; char msg[128]; ECPGdebug(1, stderr); @@ -204,7 +204,7 @@ if (sqlca.sqlcode < 0) exit (1);} p=&personal; i=&ind_personal; memset(i, 0, sizeof(ind_personal)); - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { strcpy(msg, "fetch"); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)-1,sizeof( struct birthinfo ), diff --git a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c index a367af00f37..86b9984c044 100644 --- a/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c +++ b/src/interfaces/ecpg/test/expected/preproc-whenever_do_continue.c @@ -33,7 +33,7 @@ int main(void) - + #line 15 "whenever_do_continue.pgc" @@ -48,6 +48,9 @@ int main(void) float comm ; } emp ; +#line 16 "whenever_do_continue.pgc" + int loopcount ; + #line 17 "whenever_do_continue.pgc" char msg [ 128 ] ; /* exec sql end declare section */ @@ -119,7 +122,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 42 "whenever_do_continue.pgc" - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch c", ECPGt_EOIT, ECPGt_char,&(emp.ename),(long)12,(long)1,(12)*sizeof(char), diff --git a/src/interfaces/ecpg/test/expected/sql-fetch.c b/src/interfaces/ecpg/test/expected/sql-fetch.c index b547b25c7a8..b1b13aeb752 100644 --- a/src/interfaces/ecpg/test/expected/sql-fetch.c +++ b/src/interfaces/ecpg/test/expected/sql-fetch.c @@ -25,13 +25,13 @@ int main() { /* exec sql begin declare section */ - + #line 9 "fetch.pgc" char str [ 25 ] ; #line 10 "fetch.pgc" - int i , count = 1 ; + int i , count = 1 , loopcount ; /* exec sql end declare section */ #line 11 "fetch.pgc" @@ -112,7 +112,7 @@ if (sqlca.sqlcode < 0) sqlprint();} /* exec sql whenever not found break ; */ #line 30 "fetch.pgc" - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in C", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, @@ -191,7 +191,7 @@ if (sqlca.sqlcode < 0) sqlprint();} /* exec sql whenever not found break ; */ #line 48 "fetch.pgc" - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 1 in D", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, diff --git a/src/interfaces/ecpg/test/expected/sql-quote.c b/src/interfaces/ecpg/test/expected/sql-quote.c index 0a3b77c5756..7943384fd87 100644 --- a/src/interfaces/ecpg/test/expected/sql-quote.c +++ b/src/interfaces/ecpg/test/expected/sql-quote.c @@ -25,13 +25,13 @@ int main() { /* exec sql begin declare section */ - + #line 9 "quote.pgc" char var [ 25 ] ; #line 10 "quote.pgc" - int i ; + int i , loopcount ; /* exec sql end declare section */ #line 11 "quote.pgc" @@ -176,7 +176,7 @@ if (sqlca.sqlcode < 0) sqlprint();} #line 47 "quote.pgc" - while (true) + for (loopcount = 0; loopcount < 100; loopcount++) { { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch C", ECPGt_EOIT, ECPGt_int,&(i),(long)1,(long)1,sizeof(int), diff --git a/src/interfaces/ecpg/test/pgtypeslib/nan_test.pgc b/src/interfaces/ecpg/test/pgtypeslib/nan_test.pgc index bc682b93d56..7df08194e19 100644 --- a/src/interfaces/ecpg/test/pgtypeslib/nan_test.pgc +++ b/src/interfaces/ecpg/test/pgtypeslib/nan_test.pgc @@ -18,7 +18,7 @@ int main(void) { exec sql begin declare section; - int id; + int id, loopcount; double d; numeric *num; char val[16]; @@ -34,7 +34,7 @@ main(void) exec sql declare cur cursor for select id, d, d from nantest1; exec sql open cur; - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { exec sql fetch from cur into :id, :d, :val; if (sqlca.sqlcode) @@ -50,7 +50,7 @@ main(void) exec sql close cur; exec sql open cur; - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { exec sql fetch from cur into :id, :d, :val; if (sqlca.sqlcode) @@ -76,7 +76,7 @@ main(void) exec sql declare cur1 cursor for select id, d, d from nantest2; exec sql open cur1; - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { exec sql fetch from cur1 into :id, :num, :val; if (sqlca.sqlcode) diff --git a/src/interfaces/ecpg/test/preproc/autoprep.pgc b/src/interfaces/ecpg/test/preproc/autoprep.pgc index 31c3ab7a56e..d3d9305da5b 100644 --- a/src/interfaces/ecpg/test/preproc/autoprep.pgc +++ b/src/interfaces/ecpg/test/preproc/autoprep.pgc @@ -50,7 +50,7 @@ static void test(void) { EXEC SQL WHENEVER NOT FOUND DO BREAK; i = 0; - while (1) + while (i < 100) { EXEC SQL FETCH cur1 INTO :item1:ind1; printf("item[%d] = %d\n", i, ind1 ? -1 : item1); diff --git a/src/interfaces/ecpg/test/preproc/outofscope.pgc b/src/interfaces/ecpg/test/preproc/outofscope.pgc index b03743c991f..c22003e30d9 100644 --- a/src/interfaces/ecpg/test/preproc/outofscope.pgc +++ b/src/interfaces/ecpg/test/preproc/outofscope.pgc @@ -66,7 +66,7 @@ main (void) { MYTYPE *myvar; MYNULLTYPE *mynullvar; - + int loopcount; char msg[128]; ECPGdebug(1, stderr); @@ -95,7 +95,7 @@ main (void) exec sql whenever not found do break; - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { memset(myvar, 0, sizeof(MYTYPE)); get_record1(); diff --git a/src/interfaces/ecpg/test/preproc/variable.pgc b/src/interfaces/ecpg/test/preproc/variable.pgc index 697a7dc8143..423a01c16e2 100644 --- a/src/interfaces/ecpg/test/preproc/variable.pgc +++ b/src/interfaces/ecpg/test/preproc/variable.pgc @@ -35,7 +35,7 @@ exec sql end declare section; exec sql char *married = NULL; exec sql long ind_married; exec sql ind children; - + int loopcount; char msg[128]; ECPGdebug(1, stderr); @@ -67,7 +67,7 @@ exec sql end declare section; p=&personal; i=&ind_personal; memset(i, 0, sizeof(ind_personal)); - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { strcpy(msg, "fetch"); exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint; printf("%8.8s", personal.name.arr); diff --git a/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc index 2a925a3c54f..146afecbbba 100644 --- a/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc +++ b/src/interfaces/ecpg/test/preproc/whenever_do_continue.pgc @@ -13,7 +13,7 @@ int main(void) float sal; float comm; } emp; - + int loopcount; char msg[128]; exec sql end declare section; @@ -41,7 +41,7 @@ int main(void) /* The DO CONTINUE makes the loop start at the next iteration when an error occurs.*/ exec sql whenever sqlerror do continue; - while (1) + for (loopcount = 0; loopcount < 100; loopcount++) { exec sql fetch c into :emp; /* The employees with non-NULL commissions will be displayed. */ diff --git a/src/interfaces/ecpg/test/sql/fetch.pgc b/src/interfaces/ecpg/test/sql/fetch.pgc index aade678efbe..8a5d07994ab 100644 --- a/src/interfaces/ecpg/test/sql/fetch.pgc +++ b/src/interfaces/ecpg/test/sql/fetch.pgc @@ -7,7 +7,7 @@ EXEC SQL INCLUDE ../regression; int main() { EXEC SQL BEGIN DECLARE SECTION; char str[25]; - int i, count=1; + int i, count=1, loopcount; EXEC SQL END DECLARE SECTION; ECPGdebug(1, stderr); @@ -28,7 +28,7 @@ int main() { EXEC SQL OPEN C; EXEC SQL WHENEVER NOT FOUND DO BREAK; - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { EXEC SQL FETCH 1 IN C INTO :i, :str; printf("%d: %s\n", i, str); } @@ -46,7 +46,7 @@ int main() { EXEC SQL OPEN D using 1; EXEC SQL WHENEVER NOT FOUND DO BREAK; - while (1) { + for (loopcount = 0; loopcount < 100; loopcount++) { EXEC SQL FETCH 1 IN D INTO :i, :str; printf("%d: %s\n", i, str); } diff --git a/src/interfaces/ecpg/test/sql/quote.pgc b/src/interfaces/ecpg/test/sql/quote.pgc index 9dd997323cc..83efb034840 100644 --- a/src/interfaces/ecpg/test/sql/quote.pgc +++ b/src/interfaces/ecpg/test/sql/quote.pgc @@ -7,7 +7,7 @@ EXEC SQL INCLUDE ../regression; int main() { EXEC SQL BEGIN DECLARE SECTION; char var[25]; - int i; + int i, loopcount; EXEC SQL END DECLARE SECTION; ECPGdebug(1, stderr); @@ -46,7 +46,7 @@ int main() { EXEC SQL WHENEVER NOT FOUND DO BREAK; - while (true) + for (loopcount = 0; loopcount < 100; loopcount++) { EXEC SQL FETCH C INTO :i, :var; printf("value: %d %s\n", i, var);