1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00

0029344: Foundation Classes, TCollection_AsciiString - replace confusing strncpy with memcpy

strncpy() usage within TCollection_AsciiString has been replaced by memcpy()
where string length has been already determined.

TCollection_AsciiString::SetValue() now throws exception
on attempt to set '\0' - TCollection_AsciiString::Trunc() should be used instead.
TCollection_AsciiString(const char* , int ) has been modified to properly set string length
in case of NULL-terminator appeared earlier then specified length.

Interface_LineBuffer has been revised for using NCollection_Array1 instead of TCollection_AsciiString
to avoid misusing TCollection_AsciiString interface.
This commit is contained in:
kgv 2017-11-24 18:37:01 +03:00 committed by bugmaster
parent 15669413da
commit 48a2dd2012
3 changed files with 254 additions and 218 deletions

View File

@ -17,142 +17,193 @@
#include <TCollection_AsciiString.hxx>
#include <TCollection_HAsciiString.hxx>
// LineBuffer, c est une String avec une Longueur reservee fixe au depart
// et une longueur effective <thelen>. theline(thelen+1) vaut '\0'
Interface_LineBuffer::Interface_LineBuffer (const Standard_Integer size)
: theline (size+1,' ')
: myLine (1, size+1)
{
theline.SetValue(1,'\0');
themax = size; theinit = thelen = theget = thekeep = thefriz = 0;
myLine.SetValue (1, '\0');
myMax = size;
myInit = myLen = myGet = myKeep = myFriz = 0;
}
void Interface_LineBuffer::SetMax (const Standard_Integer max)
void Interface_LineBuffer::SetMax (const Standard_Integer theMax)
{
if (max > theline.Length()) throw Standard_OutOfRange("Interface LineBuffer : SetMax");
if (max <= 0) themax = theline.Length();
else themax = max;
if (theMax > myLine.Length())
{
throw Standard_OutOfRange("Interface LineBuffer : SetMax");
}
if (theMax <= 0)
{
myMax = myLine.Length();
}
else
{
myMax = theMax;
}
}
void Interface_LineBuffer::SetInitial (const Standard_Integer initial)
void Interface_LineBuffer::SetInitial (const Standard_Integer theInitial)
{
if (thefriz > 0) return;
if (initial >= themax) throw Standard_OutOfRange("Interface LineBuffer : SetInitial");
if (initial <= 0) theinit = 0;
else theinit = initial;
if (myFriz > 0)
{
return;
}
if (theInitial >= myMax)
{
throw Standard_OutOfRange("Interface LineBuffer : SetInitial");
}
if (theInitial <= 0)
{
myInit = 0;
}
else
{
myInit = theInitial;
}
}
void Interface_LineBuffer::SetKeep ()
{ thekeep = -thelen; }
Standard_Boolean Interface_LineBuffer::CanGet (const Standard_Integer more)
void Interface_LineBuffer::SetKeep()
{
theget = more;
if ((thelen + theinit + more) <= themax) return Standard_True;
if (thekeep < 0) thekeep = -thekeep;
myKeep = -myLen;
}
Standard_Boolean Interface_LineBuffer::CanGet (const Standard_Integer theMore)
{
myGet = theMore;
if ((myLen + myInit + theMore) <= myMax)
{
return Standard_True;
}
if (myKeep < 0)
{
myKeep = -myKeep;
}
return Standard_False;
}
Standard_CString Interface_LineBuffer::Content () const
{ return theline.ToCString(); }
Standard_Integer Interface_LineBuffer::Length () const
{ return thelen + theinit; } // +theinit : longueur vraie avec blancs
void Interface_LineBuffer::FreezeInitial ()
{ thefriz = theinit+1; theinit = 0; }
void Interface_LineBuffer::Clear ()
void Interface_LineBuffer::FreezeInitial()
{
theget = thekeep = thelen = thefriz = 0;
theline.SetValue(1,'\0');
myFriz = myInit + 1;
myInit = 0;
}
void Interface_LineBuffer::Clear()
{
myGet = myKeep = myLen = myFriz = 0;
myLine.SetValue (1, '\0');
}
// .... RESULTATS ....
void Interface_LineBuffer::Prepare ()
void Interface_LineBuffer::Prepare()
{
// ATTENTION aux blanx initiaux
if (theinit > 0) {
Standard_Integer i; // svv Jan11 2000 : porting on DEC
// pdn Protection
if( (thelen +theinit) > themax)
if (myInit > 0)
{
if ((myLen + myInit) > myMax)
{
return;
for (i = thelen + 1; i > 0; i --) {
theline.SetValue(i + theinit, theline.Value(i));
}
for (i = 1; i <= theinit; i ++) theline.SetValue(i,' ');
for (Standard_Integer i = myLen + 1; i > 0; --i)
{
myLine.SetValue (i + myInit, myLine.Value (i));
}
for (Standard_Integer i = 1; i <= myInit; ++i)
{
myLine.SetValue (i, ' ');
}
}
// GERER KEEP : est-il jouable ? sinon, annuler. sioui, noter la jointure
if (thekeep > 0) thekeep += (theinit+1); // theinit, et +1 car Keep INCLUS
if (thekeep > 0)
{ if ((thelen + theget + theinit - thekeep) >= themax) thekeep = 0; }
if (thekeep > 0)
{ thekept = theline.Value(thekeep); theline.SetValue(thekeep,'\0'); }
}
void Interface_LineBuffer::Keep ()
{
// Si Keep, sauver de thekeep + 1 a thelen (+1 pour 0 final)
if (thekeep > 0) {
theline.SetValue(1,thekept);
for (Standard_Integer i = thekeep+1; i <= thelen+theinit+1; i ++) {
theline.SetValue(i-thekeep+1, theline.Value(i));
}
thelen = thelen+theinit-thekeep+1;
if (myKeep > 0)
{
myKeep += (myInit + 1); // myInit, et +1 car Keep INCLUS
}
if (myKeep > 0)
{
if ((myLen + myGet + myInit - myKeep) >= myMax)
{
myKeep = 0;
}
}
if (myKeep > 0)
{
myKept = myLine.Value (myKeep);
myLine.SetValue (myKeep, '\0');
}
else Clear();
theget = thekeep = 0;
if (thefriz > 0) { theinit = thefriz - 1; thefriz = 0; }
}
void Interface_LineBuffer::Keep()
{
// Si Keep, sauver de myKeep + 1 a myLen (+1 pour 0 final)
if (myKeep > 0)
{
myLine.SetValue (1, myKept);
for (Standard_Integer i = myKeep + 1; i <= myLen + myInit + 1; ++i)
{
myLine.SetValue (i - myKeep + 1, myLine.Value (i));
}
myLen = myLen + myInit - myKeep + 1;
}
else
{
Clear();
}
myGet = myKeep = 0;
if (myFriz > 0)
{
myInit = myFriz - 1;
myFriz = 0;
}
}
void Interface_LineBuffer::Move (TCollection_AsciiString& str)
void Interface_LineBuffer::Move (TCollection_AsciiString& theStr)
{
Prepare();
str.AssignCat(theline.ToCString());
theStr.AssignCat (&myLine.First());
Keep();
}
void Interface_LineBuffer::Move (const Handle(TCollection_HAsciiString)& str)
void Interface_LineBuffer::Move (const Handle(TCollection_HAsciiString)& theStr)
{
Prepare();
str->AssignCat(theline.ToCString());
theStr->AssignCat (&myLine.First());
Keep();
}
Handle(TCollection_HAsciiString) Interface_LineBuffer::Moved ()
Handle(TCollection_HAsciiString) Interface_LineBuffer::Moved()
{
Prepare();
Handle(TCollection_HAsciiString) R =
new TCollection_HAsciiString(theline.ToCString());
Handle(TCollection_HAsciiString) R = new TCollection_HAsciiString (&myLine.First());
Keep();
return R;
}
// .... AJOUTS ....
void Interface_LineBuffer::Add (const Standard_CString text)
{ Add (text,(Standard_Integer)strlen(text)); }
void Interface_LineBuffer::Add
(const Standard_CString text, const Standard_Integer lntext)
void Interface_LineBuffer::Add (const Standard_CString theText)
{
Standard_Integer lnt =
(lntext > (themax-thelen-theinit) ? (themax-thelen-theinit) : lntext);
for (Standard_Integer i = 1; i <= lnt; i ++)
theline.SetValue (thelen+i, text[i-1]);
thelen += lnt;
theline.SetValue (thelen+1, '\0');
Add (theText, (Standard_Integer )strlen (theText));
}
void Interface_LineBuffer::Add (const TCollection_AsciiString& text)
{ Add ( text.ToCString() , text.Length() ); }
void Interface_LineBuffer::Add (const Standard_Character text)
void Interface_LineBuffer::Add (const Standard_CString text, const Standard_Integer lntext)
{
theline.SetValue (thelen+1,text);
thelen ++;
theline.SetValue (thelen+1,'\0');
Standard_Integer lnt = (lntext > (myMax - myLen - myInit) ? (myMax - myLen - myInit) : lntext);
for (Standard_Integer i = 1; i <= lnt; ++i)
{
myLine.SetValue (myLen + i, text[i-1]);
}
myLen += lnt;
myLine.SetValue (myLen + 1, '\0');
}
void Interface_LineBuffer::Add (const TCollection_AsciiString& theText)
{
Add (theText.ToCString(), theText.Length());
}
void Interface_LineBuffer::Add (const Standard_Character theText)
{
myLine.SetValue (myLen + 1, theText);
++myLen;
myLine.SetValue (myLen + 1, '\0');
}

View File

@ -17,19 +17,8 @@
#ifndef _Interface_LineBuffer_HeaderFile
#define _Interface_LineBuffer_HeaderFile
#include <Standard.hxx>
#include <Standard_DefineAlloc.hxx>
#include <Standard_Handle.hxx>
#include <TCollection_AsciiString.hxx>
#include <Standard_Integer.hxx>
#include <Standard_Character.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_CString.hxx>
class Standard_OutOfRange;
class TCollection_AsciiString;
class TCollection_HAsciiString;
#include <NCollection_Array1.hxx>
#include <TCollection_HAsciiString.hxx>
//! Simple Management of a Line Buffer, to be used by Interface
//! File Writers.
@ -66,11 +55,10 @@ public:
Standard_EXPORT Standard_Boolean CanGet (const Standard_Integer more);
//! Returns the Content of the LineBuffer
//! was C++ : return const
Standard_EXPORT Standard_CString Content() const;
Standard_CString Content() const { return &myLine.First(); }
//! Returns the Length of the LineBuffer
Standard_EXPORT Standard_Integer Length() const;
Standard_Integer Length() const { return myLen + myInit; }
//! Clears completely the LineBuffer
Standard_EXPORT void Clear();
@ -104,18 +92,8 @@ public:
//! Adds a text made of only ONE Character
Standard_EXPORT void Add (const Standard_Character text);
protected:
private:
//! Prepares Move : Inserts Initial Blanks if required, and
//! determines if SetKeep can be supported (it cannot be if Length
//! + Next String to get (see CanGet) overpass Max Size)
@ -125,23 +103,17 @@ private:
//! to Clear
Standard_EXPORT void Keep();
private:
TCollection_AsciiString theline;
Standard_Integer themax;
Standard_Integer theinit;
Standard_Integer thekeep;
Standard_Integer theget;
Standard_Integer thelen;
Standard_Integer thefriz;
Standard_Character thekept;
NCollection_Array1<Standard_Character> myLine;
Standard_Integer myMax;
Standard_Integer myInit;
Standard_Integer myKeep;
Standard_Integer myGet;
Standard_Integer myLen;
Standard_Integer myFriz;
Standard_Character myKept;
};
#endif // _Interface_LineBuffer_HeaderFile

View File

@ -59,35 +59,39 @@ TCollection_AsciiString::TCollection_AsciiString()
// ----------------------------------------------------------------------------
// Create an asciistring from a Standard_CString
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(const Standard_CString astring)
: mystring(0), mylength(0)
TCollection_AsciiString::TCollection_AsciiString (const Standard_CString theString)
: mystring(0),
mylength(0)
{
if (astring) {
mylength = Standard_Integer( strlen(astring) );
mystring = Allocate(mylength+1);
strncpy(mystring,astring,mylength);
mystring[mylength] = '\0';
}
else {
throw Standard_NullObject("TCollection_AsciiString : parameter 'astring'");
if (theString == NULL)
{
throw Standard_NullObject ("TCollection_AsciiString(): NULL pointer passed to constructor");
}
mylength = Standard_Integer (strlen (theString));
mystring = Allocate (mylength + 1);
memcpy (mystring, theString, mylength);
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
// Create an asciistring from a Standard_CString
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(const Standard_CString astring,
const Standard_Integer aLen )
: mystring(0), mylength(aLen)
TCollection_AsciiString::TCollection_AsciiString (const Standard_CString theString,
const Standard_Integer theLen)
: mystring (NULL),
mylength (0)
{
if (astring) {
mystring = Allocate(mylength+1);
strncpy( mystring , astring , mylength );
mystring [ mylength ] = '\0' ;
}
else {
throw Standard_NullObject("TCollection_AsciiString : parameter 'astring'");
if (theString == NULL)
{
throw Standard_NullObject ("TCollection_AsciiString(): NULL pointer passed to constructor");
}
for (; mylength < theLen && theString[mylength] != '\0'; ++mylength) {}
mystring = Allocate (mylength + 1);
memcpy (mystring, theString, mylength);
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
@ -130,7 +134,7 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_Integer aValue)
char t [13];
mylength = Sprintf( t,"%d",aValue);
mystring = Allocate(mylength+1);
strncpy( mystring , t , mylength );
memcpy (mystring, t, mylength);
mystring[mylength] = '\0';
}
@ -143,77 +147,80 @@ TCollection_AsciiString::TCollection_AsciiString(const Standard_Real aValue)
char t [50];
mylength = Sprintf( t,"%g",aValue);
mystring = Allocate(mylength+1);
strncpy( mystring , t , mylength );
memcpy (mystring, t, mylength);
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
// Create an asciistring from an asciistring
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(const TCollection_AsciiString& astring)
: mystring(0)
TCollection_AsciiString::TCollection_AsciiString (const TCollection_AsciiString& theString)
: mystring (Allocate (theString.mylength + 1)),
mylength (theString.mylength)
{
mylength = astring.mylength;
mystring = Allocate(mylength+1);
if ( mylength )
strncpy(mystring,astring.mystring,mylength);
if (mylength != 0)
{
memcpy (mystring, theString.mystring, mylength);
}
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
// Create an asciistring from a character
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(
const TCollection_AsciiString& astring ,
const Standard_Character other )
: mystring(0)
TCollection_AsciiString::TCollection_AsciiString (const TCollection_AsciiString& theString,
const Standard_Character theChar)
: mystring (NULL),
mylength (theString.mylength + 1)
{
mylength = astring.mylength + 1 ;
mystring = Allocate(mylength+1);
if ( astring.mylength ) {
strncpy( mystring , astring.mystring , astring.mylength ) ;
mystring = Allocate (mylength + 1);
if (theString.mylength != 0)
{
memcpy (mystring, theString.mystring, theString.mylength);
}
mystring[mylength-1] = other ;
mystring[mylength] = '\0' ;
mystring[mylength - 1] = theChar;
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
// Create an asciistring from an asciistring
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(
const TCollection_AsciiString& astring ,
const Standard_CString other )
: mystring(0)
TCollection_AsciiString::TCollection_AsciiString (const TCollection_AsciiString& theString1,
const Standard_CString theString2)
: mystring (0)
{
Standard_Integer otherlength = Standard_Integer( other ? strlen( other ) : 0 );
mylength = astring.mylength + otherlength ;
mystring = Allocate(mylength+1);
if ( astring.mylength ) {
strncpy( mystring , astring.mystring , astring.mylength ) ;
const Standard_Integer aStr2Len = Standard_Integer (theString2 ? strlen (theString2) : 0);
mylength = theString1.mylength + aStr2Len;
mystring = Allocate (mylength + 1);
if (theString1.mylength != 0)
{
memcpy (mystring, theString1.mystring, theString1.mylength);
}
if ( otherlength ) {
strncpy( mystring + astring.mylength, other, otherlength );
if (aStr2Len != 0)
{
memcpy (mystring + theString1.mylength, theString2, aStr2Len);
}
mystring[ mylength ] = '\0';
mystring[mylength] = '\0';
}
// ----------------------------------------------------------------------------
// Create an asciistring from an asciistring
// ----------------------------------------------------------------------------
TCollection_AsciiString::TCollection_AsciiString(
const TCollection_AsciiString& astring ,
const TCollection_AsciiString& other )
: mystring(0)
TCollection_AsciiString::TCollection_AsciiString (const TCollection_AsciiString& theString1,
const TCollection_AsciiString& theString2)
: mystring (0),
mylength (theString1.mylength + theString2.mylength)
{
mylength = astring.mylength + other.mylength ;
mystring = Allocate(mylength+1);
if ( astring.mylength ) {
strncpy( mystring , astring.mystring , astring.mylength ) ;
mystring = Allocate (mylength + 1);
if (theString1.mylength)
{
memcpy (mystring, theString1.mystring, theString1.mylength);
}
if ( other.mylength ) {
strncpy( mystring + astring.mylength, other.mystring , other.mylength ) ;
if (theString2.mylength != 0)
{
memcpy (mystring + theString1.mylength, theString2.mystring, theString2.mylength);
}
mystring[mylength] = '\0' ;
mystring[mylength] = '\0';
}
//---------------------------------------------------------------------------
@ -298,33 +305,34 @@ void TCollection_AsciiString::AssignCat(const Standard_Character other)
// ----------------------------------------------------------------------------
// AssignCat
// ----------------------------------------------------------------------------
void TCollection_AsciiString::AssignCat(const Standard_CString other)
void TCollection_AsciiString::AssignCat (const Standard_CString theOther)
{
if (other) {
Standard_Integer otherlength = Standard_Integer( strlen( other ));
if ( otherlength ) {
Standard_Integer newlength = mylength+otherlength;
mystring = Reallocate (mystring, newlength + 1);
strncpy( mystring + mylength, other, otherlength+1 );
mylength = newlength;
}
}
else {
if (theOther == NULL)
{
throw Standard_NullObject("TCollection_AsciiString::Operator += parameter other");
}
Standard_Integer anOtherLen = Standard_Integer (strlen (theOther));
if (anOtherLen != 0)
{
const Standard_Integer aNewLen = mylength + anOtherLen;
mystring = Reallocate (mystring, aNewLen + 1);
memcpy (mystring + mylength, theOther, anOtherLen + 1);
mylength = aNewLen;
}
}
// ----------------------------------------------------------------------------
// AssignCat
// ----------------------------------------------------------------------------
void TCollection_AsciiString::AssignCat(const TCollection_AsciiString& other)
void TCollection_AsciiString::AssignCat (const TCollection_AsciiString& theOther)
{
if (other.mylength) {
Standard_Integer newlength = mylength+other.mylength;
mystring = Reallocate (mystring, newlength + 1);
strncpy( mystring + mylength, other.mystring, other.mylength+1 );
mylength = newlength;
if (theOther.mylength != 0)
{
const Standard_Integer aNewLen = mylength + theOther.mylength;
mystring = Reallocate (mystring, aNewLen + 1);
memcpy (mystring + mylength, theOther.mystring, theOther.mylength + 1);
mylength = aNewLen;
}
}
@ -394,7 +402,7 @@ void TCollection_AsciiString::Copy(const Standard_CString fromwhere)
if (fromwhere) {
mylength = Standard_Integer( strlen( fromwhere ));
mystring = Reallocate (mystring, mylength + 1);
strncpy( mystring, fromwhere, mylength+1 );
memcpy (mystring, fromwhere, mylength + 1);
}
else {
mylength = 0;
@ -410,7 +418,7 @@ void TCollection_AsciiString::Copy(const TCollection_AsciiString& fromwhere)
if (fromwhere.mystring) {
mylength = fromwhere.mylength;
mystring = Reallocate (mystring, mylength + 1);
strncpy( mystring, fromwhere.mystring, mylength+1 );
memcpy (mystring, fromwhere.mystring, mylength + 1);
}
else {
mylength = 0;
@ -898,7 +906,7 @@ void TCollection_AsciiString::Read(Standard_IStream& astream)
// put to string
mylength = Standard_Integer( strlen( buffer ));
mystring = Reallocate (mystring, mylength + 1);
strncpy(mystring,buffer,mylength);
memcpy (mystring, buffer, mylength);
mystring[mylength] = '\0';
}
@ -1107,16 +1115,18 @@ Standard_Integer TCollection_AsciiString::SearchFromEnd
// ----------------------------------------------------------------------------
// SetValue
// ----------------------------------------------------------------------------
void TCollection_AsciiString::SetValue(const Standard_Integer where,
const Standard_Character what)
void TCollection_AsciiString::SetValue (const Standard_Integer theWhere,
const Standard_Character theWhat)
{
if (where > 0 && where <= mylength) {
mystring[where-1] = what;
if (theWhere <= 0 || theWhere > mylength)
{
throw Standard_OutOfRange ("TCollection_AsciiString::SetValue(): out of range location");
}
else {
throw Standard_OutOfRange("TCollection_AsciiString::SetValue : "
"parameter where");
else if (theWhat == '\0')
{
throw Standard_OutOfRange ("TCollection_AsciiString::SetValue(): NULL terminator is passed");
}
mystring[theWhere - 1] = theWhat;
}
// ----------------------------------------------------------------------------
@ -1206,10 +1216,13 @@ void TCollection_AsciiString::SubString(const Standard_Integer FromIndex,
{
if (ToIndex > mylength || FromIndex <= 0 || FromIndex > ToIndex )
{
throw Standard_OutOfRange();
}
Standard_Integer newlength = ToIndex-FromIndex+1;
res.mystring =Reallocate (res.mystring, newlength + 1);
strncpy( res.mystring, mystring + FromIndex - 1, newlength );
memcpy (res.mystring, mystring + FromIndex - 1, newlength);
res.mystring[newlength] = '\0';
res.mylength = newlength;
return ;