kicad-developers team mailing list archive
-
kicad-developers team
-
Mailing list archive
-
Message #16912
Re: 3D Viewer crushes whole KiCAD with this file
Ok, I can confirm I get an identical crash. I believe I fixed it in
another patch I submitted in the another email. I attached them to
this email if you could try them.
This however stops the crash but the LED model won't load. I will look
into seeing data in the file is causing the buffer overrun.
On Wed, Feb 18, 2015 at 3:17 PM, LordBlick <lordblick@xxxxxxxxx> wrote:
> In response to a message written on 18.02.2015, 19:24, from Mark Roszko:
>>
>> The <optimized_out> is for the function argument.
>>
>>
>> @LordBlick, could you compile with -DCMAKE_BUILD_TYPE=Debug and do the
>> backtrace after it fails with that build.
>
> At the rpmbuild level, simply attached „--debug” to the cmd prompt.
> Here you go, here you have it:
> --------------------------------------------------------------
> Application: kicad
> Version: (after 2015-jan-16 BZR unknown)-BZR5430 Debug build
> wxWidgets: Version 3.0.1 (release,wchar_t,compiler with C++ ABI 1002,GCC
> 4.9.2,wx containers,compatible with 2.8)
> Platform: Linux 3.18.5-1 x86_64, 64 bit, Little endian, wxGTK
> Boost version: 1.57.0
> USE_WX_GRAPHICS_CONTEXT=OFF
> USE_WX_OVERLAY=OFF
> KICAD_SCRIPTING=ON
> KICAD_SCRIPTING_MODULES=ON
> KICAD_SCRIPTING_WXPYTHON=ON
> USE_FP_LIB_TABLE=HARD_CODED_ON
> BUILD_GITHUB_PLUGIN=OFF
> KICAD_USE_WEBKIT=OFF
> --------------------------------------------------------------
> $ gdb kicad
> GNU gdb (GDB) 7.8.1-1 (PLD Linux)
> Copyright (C) 2014 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-pld-linux".
> Type "show configuration" for configuration details.
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Find the GDB manual and other documentation resources online at:
> <http://www.gnu.org/software/gdb/documentation/>.
> For help, type "help".
> Type "apropos word" to search for commands related to "word"...
> Reading symbols from kicad...done.
> (gdb) start
> Temporary breakpoint 1 at 0x46f355: file
> /usr/src/debug/kicad-sources-BZR.5430-main/kicad/kicad.cpp, line 300.
> Starting program: /usr/bin/kicad
> warning: Could not load shared library symbols for linux-vdso.so.1.
> Do you need "set solib-search-path" or "set sysroot"?
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib64/libthread_db.so.1".
>
> Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdae8) at
> /usr/src/debug/kicad-sources-BZR.5430-main/kicad/kicad.cpp:300
> 300 IMPLEMENT_APP( APP_KICAD );
> (gdb) continue
> Continuing.
> LIB_ENV_VAR:'/usr/bin'
> ElemsClear: clearing all _ELEMS for project
> SetProjectFullName: old:'' new:'${ProjectPath}/PowerHV.pro'
> [New Thread 0x7fffda3b1700 (LWP 5364)]
> [New Thread 0x7fffd9bb0700 (LWP 5365)]
> [New Thread 0x7fffd93af700 (LWP 5366)]
> FileWatcherReset: add '${ProjectPath}/_CAD'
> FileWatcherReset: add '${ProjectPath}/_doc'
> FileWatcherReset: add '${ProjectPath}/_old'
> FileWatcherReset: add '${ProjectPath}/gerberAndDrill'
> FileWatcherReset: add '${ProjectPath}/Mount'
> FileWatcherReset: add '${ProjectPath}/panelProd'
> FileWatcherReset: watched paths:
> ${ProjectPath}/_old/
> ${ProjectPath}/_doc/
> ${ProjectPath}/
> ${ProjectPath}/panelProd/
> ${ProjectPath}/_CAD/
> ${ProjectPath}/gerberAndDrill/
> ${ProjectPath}/Mount/
> kiface SEARCH_STACK:
> [ 0]:/usr/share/kicad/modules
> [ 1]:/usr/share/kicad/modules/packages3d
> [ 2]:/usr/share/kicad/template
> [ 3]:/usr/local/share
> [Thread 0x7fffd93af700 (LWP 5366) exited]
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
> <drawsegment> Need ::Show() override for this class </drawsegment>
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007fffcb545786 in VRML2_MODEL_PARSER::Load (this=0x37d00b0,
> aFilename=..., aVrmlunits_to_3Dunits=0.041753652758311229)
> at
> /usr/src/debug/kicad-sources-BZR.5430-main/3d-viewer/vrml_v2_modelparser.cpp:134
> 134 }
> (gdb) backtrace
> #0 0x00007fffcb545786 in VRML2_MODEL_PARSER::Load (this=0x37d00b0,
> aFilename=..., aVrmlunits_to_3Dunits=0.041753652758311229)
> at
> /usr/src/debug/kicad-sources-BZR.5430-main/3d-viewer/vrml_v2_modelparser.cpp:134
> #1 0x312d2c372c39312c in ?? ()
> [Many of unresolved addresses excised - it's hard to dbg rebuild all OS
> libs…]
> #360 0x00007fff0000000e in ?? ()
> #361 0x00007ffff26ba023 in g_value_unset () from
> /usr/lib64/libgobject-2.0.so.0
> #362 0x00007ffff26ae994 in g_signal_emit_valist () from
> /usr/lib64/libgobject-2.0.so.0
> Backtrace stopped: Cannot access memory at address 0x352c312d2c353134
> (gdb) continue
> Continuing.
> [Thread 0x7fffd9bb0700 (LWP 5365) exited]
> [Thread 0x7fffda3b1700 (LWP 5364) exited]
>
> Program terminated with signal SIGSEGV, Segmentation fault.
> The program no longer exists.
> --------------------------------------------------------------
> Again, build prompt & flags:
> cd ~/rpm/BUILD/kicad-sources-BZR.5430-main/build/3d-viewer &&
> /usr/bin/x86_64-pld-linux-g++ -DHAVE_STDINT_H -DKICAD_KEEPCASE
> -DKICAD_SCRIPTING -DKICAD_SCRIPTING_MODULES -DKICAD_SCRIPTING_WXPYTHON
> -DPCBNEW -DUSE_OPENMP -DWXUSINGDLL -DWX_COMPATIBILITY -D_FILE_OFFSET_BITS=64
> -D__WXGTK__ -DwxDEBUG_LEVEL=0 -Wall -fopenmp -fPIC
> -Wno-unused-local-typedefs -Wno-strict-aliasing -pthread -g3 -ggdb3 -DDEBUG
> -Wno-deprecated-declarations
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/include
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/3d-viewer/. -isystem
> /usr/lib64/wx/include/gtk2-unicode-3.0 -isystem /usr/include/wx-3.0
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/3d-viewer/textures
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/3d-viewer/../pcbnew
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/3d-viewer/../polygon
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/build -I/usr/include/python2.7
> -I~/rpm/BUILD/kicad-sources-BZR.5430-main/scripting -o
> CMakeFiles/3d-viewer.dir/vrml_v2_modelparser.cpp.o -c
> ~/rpm/BUILD/kicad-sources-BZR.5430-main/3d-viewer/vrml_v2_modelparser.cpp
> --------------------------------------------------------------
> BTW. I've also traced pcbnew freerun mode closing segfault bug:
> --------------------------------------------------------------
> $ gdb pcbnew
> GNU gdb (GDB) 7.8.1-1 (PLD Linux)
> Copyright (C) 2014 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-pld-linux".
> Type "show configuration" for configuration details.
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Find the GDB manual and other documentation resources online at:
> <http://www.gnu.org/software/gdb/documentation/>.
> For help, type "help".
> Type "apropos word" to search for commands related to "word"...
> Reading symbols from pcbnew...done.
> (gdb) start
> Temporary breakpoint 1 at 0x43fbdc: file
> /usr/src/debug/kicad-sources-BZR.5430-main/common/single_top.cpp, line 189.
> Starting program: /usr/bin/pcbnew
> warning: Could not load shared library symbols for linux-vdso.so.1.
> Do you need "set solib-search-path" or "set sysroot"?
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib64/libthread_db.so.1".
>
> Temporary breakpoint 1, main (argc=1, argv=0x7fffffffdae8) at
> /usr/src/debug/kicad-sources-BZR.5430-main/common/single_top.cpp:189
> 189 IMPLEMENT_APP( APP_SINGLE_TOP );
> (gdb) continue
> Continuing.
> LIB_ENV_VAR:'/usr/bin'
> kiface SEARCH_STACK:
> [ 0]:/usr/share/kicad/modules
> [ 1]:/usr/share/kicad/modules/packages3d
> [ 2]:/usr/share/kicad/template
> [ 3]:/usr/local/share
> [New Thread 0x7fffd3e1c700 (LWP 5530)]
> player_destroy_handler: m_player[4] destroyed: PcbFrame
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff65aede3 in wxEntry(int&, wchar_t**) () from
> /usr/lib64/libwx_baseu-3.0.so.0
> (gdb) backtrace
> #0 0x00007ffff65aede3 in wxEntry(int&, wchar_t**) () from
> /usr/lib64/libwx_baseu-3.0.so.0
> #1 0x000000000043fbef in main (argc=1, argv=0x7fffffffdae8) at
> /usr/src/debug/kicad-sources-BZR.5430-main/common/single_top.cpp:189
> (gdb) continue
> Continuing.
> [Thread 0x7fffd3e1c700 (LWP 5530) exited]
>
> Program terminated with signal SIGSEGV, Segmentation fault.
> The program no longer exists.
> --------------------------------------------------------------
> --
> Best Regards,
> LordBlick
>
>
> _______________________________________________
> Mailing list: https://launchpad.net/~kicad-developers
> Post to : kicad-developers@xxxxxxxxxxxxxxxxxxx
> Unsubscribe : https://launchpad.net/~kicad-developers
> More help : https://help.launchpad.net/ListHelp
--
Mark
From 410c30db3a435c023fa93e9e9e38166263fd8287 Mon Sep 17 00:00:00 2001
From: Mark Roszko <mark.roszko@xxxxxxxxx>
Date: Tue, 17 Feb 2015 20:33:01 -0500
Subject: [PATCH 1/2] Fix vrml_v2_modelparser.cpp array comparisons
---
3d-viewer/vrml_v2_modelparser.cpp | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/3d-viewer/vrml_v2_modelparser.cpp b/3d-viewer/vrml_v2_modelparser.cpp
index 7cb9c3f..4d8618f 100644
--- a/3d-viewer/vrml_v2_modelparser.cpp
+++ b/3d-viewer/vrml_v2_modelparser.cpp
@@ -262,10 +262,10 @@ int VRML2_MODEL_PARSER::read_DEF_Coordinate()
while( GetNextTag( m_file, text ) )
{
- if( ( text == NULL ) || ( *text == ']' ) )
+ if( *text == ']' )
continue;
- if( ( *text == '}' ) )
+ if( *text == '}' )
return 0;
if( strcmp( text, "Coordinate" ) == 0 )
@@ -669,10 +669,10 @@ int VRML2_MODEL_PARSER::read_IndexedLineSet()
while( GetNextTag( m_file, text ) )
{
- if( ( text == NULL ) || ( *text == ']' ) )
+ if( *text == ']' )
continue;
- if( ( *text == '}' ) )
+ if( *text == '}' )
return 0;
if( strcmp( text, "Coordinate" ) == 0 )
@@ -874,10 +874,10 @@ int VRML2_MODEL_PARSER::read_CoordinateDef()
while( GetNextTag( m_file, text ) )
{
- if( ( text == NULL ) || ( *text == ']' ) )
+ if( *text == ']' )
continue;
- if( ( *text == '}' ) )
+ if( *text == '}' )
return 0;
if( strcmp( text, "point" ) == 0 )
--
1.9.1
From 1c58e335c9c160c6b32c998b4b7608e4ad9c3dd5 Mon Sep 17 00:00:00 2001
From: Mark Roszko <mark.roszko@xxxxxxxxx>
Date: Tue, 17 Feb 2015 20:52:59 -0500
Subject: [PATCH 2/2] Make GetNextTag implementation safer by checking number
of bytes read, also use bool return type as the function was used as such in
all cases
---
3d-viewer/vrml_aux.cpp | 10 +++++----
3d-viewer/vrml_aux.h | 2 +-
3d-viewer/vrml_v1_modelparser.cpp | 10 ++++-----
3d-viewer/vrml_v2_modelparser.cpp | 44 +++++++++++++++++++--------------------
4 files changed, 34 insertions(+), 32 deletions(-)
diff --git a/3d-viewer/vrml_aux.cpp b/3d-viewer/vrml_aux.cpp
index 8422efa..7611c4d 100644
--- a/3d-viewer/vrml_aux.cpp
+++ b/3d-viewer/vrml_aux.cpp
@@ -94,13 +94,13 @@ static int SkipGetChar( FILE* File )
}
-char* GetNextTag( FILE* File, char* tag )
+bool GetNextTag( FILE* File, char* tag, size_t len )
{
int c = SkipGetChar( File );
if( c == EOF )
{
- return NULL;
+ return false;
}
tag[0] = c;
@@ -109,9 +109,10 @@ char* GetNextTag( FILE* File, char* tag )
// DBG( printf( "tag[0] %c\n", tag[0] ) );
if( (c != '}') && (c != ']') )
{
+ len--;
char* dst = &tag[1];
- while( fscanf( File, "%c", dst ) )
+ while( fscanf( File, "%c", dst ) && len > 0 )
{
if( (*dst == ' ') || (*dst == '[') || (*dst == '{')
|| (*dst == '\t') || (*dst == '\n')|| (*dst == '\r') )
@@ -121,6 +122,7 @@ char* GetNextTag( FILE* File, char* tag )
}
dst++;
+ len--;
}
@@ -134,7 +136,7 @@ char* GetNextTag( FILE* File, char* tag )
}
}
- return tag;
+ return true;
}
diff --git a/3d-viewer/vrml_aux.h b/3d-viewer/vrml_aux.h
index f245ce7..718ad72 100644
--- a/3d-viewer/vrml_aux.h
+++ b/3d-viewer/vrml_aux.h
@@ -52,6 +52,6 @@ int read_NotImplemented( FILE* File, char closeChar);
int parseVertexList( FILE* File, std::vector< glm::vec3 > &dst_vector);
int parseVertex( FILE* File, glm::vec3 &dst_vertex );
int parseFloat( FILE* File, float *dst_float );
-char* GetNextTag( FILE* File, char* tag );
+bool GetNextTag( FILE* File, char* tag, size_t len );
#endif
diff --git a/3d-viewer/vrml_v1_modelparser.cpp b/3d-viewer/vrml_v1_modelparser.cpp
index ee7a2fd..97cc69b 100644
--- a/3d-viewer/vrml_v1_modelparser.cpp
+++ b/3d-viewer/vrml_v1_modelparser.cpp
@@ -88,7 +88,7 @@ void VRML1_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3
childs.clear();
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( ( *text == '}' ) || ( *text == ']' ) )
{
@@ -123,7 +123,7 @@ int VRML1_MODEL_PARSER::read_separator()
// DBG( printf( "Separator\n" ) );
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Material" ) == 0 )
{
@@ -182,7 +182,7 @@ int VRML1_MODEL_PARSER::readMaterial()
m_model->m_Materials = material;
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -230,7 +230,7 @@ int VRML1_MODEL_PARSER::readCoordinate3()
// DBG( printf( " readCoordinate3\n" ) );
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -258,7 +258,7 @@ int VRML1_MODEL_PARSER::readIndexedFaceSet()
// DBG( printf( " readIndexedFaceSet\n" ) );
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
diff --git a/3d-viewer/vrml_v2_modelparser.cpp b/3d-viewer/vrml_v2_modelparser.cpp
index 4d8618f..97ba12c 100644
--- a/3d-viewer/vrml_v2_modelparser.cpp
+++ b/3d-viewer/vrml_v2_modelparser.cpp
@@ -99,7 +99,7 @@ void VRML2_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3
childs.clear();
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( ( *text == '}' ) || ( *text == ']' ) )
{
@@ -138,7 +138,7 @@ int VRML2_MODEL_PARSER::read_Transform()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -257,10 +257,10 @@ int VRML2_MODEL_PARSER::read_DEF_Coordinate()
char text[128];
// Get the name of the definition.
- GetNextTag( m_file, text );
+ GetNextTag( m_file, text, sizeof(text) );
std::string coordinateName = text;
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
@@ -287,9 +287,9 @@ int VRML2_MODEL_PARSER::read_DEF()
{
char text[128];
- GetNextTag( m_file, text );
+ GetNextTag( m_file, text, sizeof(text) );
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -344,7 +344,7 @@ int VRML2_MODEL_PARSER::read_USE()
char text[128];
// Get the name of the definition.
- GetNextTag( m_file, text );
+ GetNextTag( m_file, text, sizeof(text) );
std::string coordinateName = text;
// Look for it in our coordinate map.
@@ -368,7 +368,7 @@ int VRML2_MODEL_PARSER::read_Shape()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -418,7 +418,7 @@ int VRML2_MODEL_PARSER::read_Appearance()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -446,7 +446,7 @@ int VRML2_MODEL_PARSER::read_material()
S3D_MATERIAL* material = NULL;
char text[128];
- if( GetNextTag( m_file, text ) )
+ if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Material" ) == 0 )
{
@@ -462,7 +462,7 @@ int VRML2_MODEL_PARSER::read_material()
}
else if( strcmp( text, "DEF" ) == 0 )
{
- if( GetNextTag( m_file, text ) )
+ if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxString mat_name;
mat_name = FROM_UTF8( text );
@@ -471,7 +471,7 @@ int VRML2_MODEL_PARSER::read_material()
GetMaster()->Insert( material );
m_model->m_Materials = material;
- if( GetNextTag( m_file, text ) )
+ if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "Material" ) == 0 )
{
@@ -482,7 +482,7 @@ int VRML2_MODEL_PARSER::read_material()
}
else if( strcmp( text, "USE" ) == 0 )
{
- if( GetNextTag( m_file, text ) )
+ if( GetNextTag( m_file, text, sizeof(text) ) )
{
wxString mat_name;
mat_name = FROM_UTF8( text );
@@ -511,7 +511,7 @@ int VRML2_MODEL_PARSER::read_Material()
char text[128];
glm::vec3 vertex;
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -593,7 +593,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
m_normalPerVertex = false;
colorPerVertex = false;
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -607,7 +607,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
if( strcmp( text, "normalPerVertex" ) == 0 )
{
- if( GetNextTag( m_file, text ) )
+ if( GetNextTag( m_file, text, sizeof(text) ) )
{
if( strcmp( text, "TRUE" ) == 0 )
{
@@ -617,7 +617,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
}
else if( strcmp( text, "colorPerVertex" ) == 0 )
{
- GetNextTag( m_file, text );
+ GetNextTag( m_file, text, sizeof(text) );
if( strcmp( text, "TRUE" ) )
{
@@ -667,7 +667,7 @@ int VRML2_MODEL_PARSER::read_IndexedLineSet()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
@@ -783,7 +783,7 @@ int VRML2_MODEL_PARSER::read_Color()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -810,7 +810,7 @@ int VRML2_MODEL_PARSER::read_Normal()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -843,7 +843,7 @@ int VRML2_MODEL_PARSER::read_Coordinate()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
{
@@ -872,7 +872,7 @@ int VRML2_MODEL_PARSER::read_CoordinateDef()
{
char text[128];
- while( GetNextTag( m_file, text ) )
+ while( GetNextTag( m_file, text, sizeof(text) ) )
{
if( *text == ']' )
continue;
--
1.9.1
Follow ups
References