Skip to content

Commit

Permalink
- Woking on MDEV-10525. Lrecl mismatch on DBF files
Browse files Browse the repository at this point in the history
  modified:   storage/connect/filamdbf.cpp
  modified:   storage/connect/filamdbf.h
  modified:   storage/connect/reldef.cpp
  • Loading branch information
Buggynours committed Sep 16, 2016
1 parent 0799cf0 commit 98cc091
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 20 deletions.
86 changes: 68 additions & 18 deletions storage/connect/filamdbf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ DBFBASE::DBFBASE(DBFBASE *txfp)
/* and header length. Set Records, check that Reclen is equal to lrecl and */
/* return the header length or 0 in case of error. */
/****************************************************************************/
int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
int DBFBASE::ScanHeader(PGLOBAL g, PSZ fn, int lrecl, int *rln, char *defpath)
{
int rc;
char filename[_MAX_PATH];
Expand All @@ -393,7 +393,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
/************************************************************************/
/* Open the input file. */
/************************************************************************/
PlugSetPath(filename, fname, defpath);
PlugSetPath(filename, fn, defpath);

if (!(infile= global_fopen(g, MSGID_CANNOT_OPEN, filename, "rb")))
return 0; // Assume file does not exist
Expand All @@ -410,11 +410,7 @@ int DBFBASE::ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath)
} else if (rc == RC_FX)
return -1;

if ((int)header.Reclen() != lrecl) {
sprintf(g->Message, MSG(BAD_LRECL), lrecl, header.Reclen());
return -1;
} // endif Lrecl

*rln = (int)header.Reclen();
Records = (int)header.Records();
return (int)header.Headlen();
} // end of ScanHeader
Expand All @@ -431,9 +427,27 @@ int DBFFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;

if (!Headlen)
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
return -1; // Error in ScanHeader
if (!Headlen) {
int rln = 0; // Record length in the file header

Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());

if (Headlen < 0)
return -1; // Error in ScanHeader

if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);

if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;

} // endif rln

} // endif Headlen

// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
Expand Down Expand Up @@ -565,7 +579,13 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)

if (Lrecl != reclen) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, reclen);
return true;

if (Accept) {
Lrecl = reclen;
PushWarning(g, Tdbp);
} else
return true;

} // endif Lrecl

hlen = HEADLEN * (n + 1) + 2;
Expand Down Expand Up @@ -641,8 +661,14 @@ bool DBFFAM::AllocateBuffer(PGLOBAL g)
if ((rc = dbfhead(g, Stream, Tdbp->GetFile(g), &header)) == RC_OK) {
if (Lrecl != (int)header.Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, header.Reclen());
return true;
} // endif Lrecl

if (Accept) {
Lrecl = header.Reclen();
PushWarning(g, Tdbp);
} else
return true;

} // endif Lrecl

Records = (int)header.Records();
Headlen = (int)header.Headlen();
Expand Down Expand Up @@ -916,9 +942,27 @@ int DBMFAM::Cardinality(PGLOBAL g)
if (!g)
return 1;

if (!Headlen)
if ((Headlen = ScanHeader(g, To_File, Lrecl, Tdbp->GetPath())) < 0)
return -1; // Error in ScanHeader
if (!Headlen) {
int rln = 0; // Record length in the file header

Headlen = ScanHeader(g, To_File, Lrecl, &rln, Tdbp->GetPath());

if (Headlen < 0)
return -1; // Error in ScanHeader

if (rln && Lrecl != rln) {
// This happens always on some Linux platforms
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, rln);

if (Accept) {
Lrecl = rln;
PushWarning(g, Tdbp);
} else
return -1;

} // endif rln

} // endif Headlen

// Set number of blocks for later use
Block = (Records > 0) ? (Records + Nrec - 1) / Nrec : 0;
Expand Down Expand Up @@ -961,8 +1005,14 @@ bool DBMFAM::AllocateBuffer(PGLOBAL g)

if (Lrecl != (int)hp->Reclen()) {
sprintf(g->Message, MSG(BAD_LRECL), Lrecl, hp->Reclen());
return true;
} // endif Lrecl

if (Accept) {
Lrecl = hp->Reclen();
PushWarning(g, Tdbp);
} else
return true;

} // endif Lrecl

Records = (int)hp->Records();
Headlen = (int)hp->Headlen();
Expand Down
2 changes: 1 addition & 1 deletion storage/connect/filamdbf.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class DllExport DBFBASE {
DBFBASE(PDBF txfp);

// Implementation
int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, char *defpath);
int ScanHeader(PGLOBAL g, PSZ fname, int lrecl, int *rlen, char *defpath);

protected:
// Default constructor, not to be used
Expand Down
6 changes: 5 additions & 1 deletion storage/connect/reldef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,11 @@ int TABDEF::GetColCatInfo(PGLOBAL g)
} // endswitch tc

// lrecl must be at least recln to avoid buffer overflow
recln= MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
if (trace)
htrc("Lrecl: Calculated=%d defined=%d\n",
recln, Hc->GetIntegerOption("Lrecl"));

recln = MY_MAX(recln, Hc->GetIntegerOption("Lrecl"));
Hc->SetIntegerOption("Lrecl", recln);
((PDOSDEF)this)->SetLrecl(recln);
} // endif Lrecl
Expand Down

0 comments on commit 98cc091

Please sign in to comment.