file-geodatabase-api icon indicating copy to clipboard operation
file-geodatabase-api copied to clipboard

Segmentation fault in EnumRows::Next() when requesting a binary field on a CDF dataset

Open rouault opened this issue 3 years ago • 0 comments

Coming from https://github.com/qgis/QGIS/issues/45760

With the attached dataset COASTS.gdb.zip, FileGDB_API-RHEL7-64gcc83 crashes on the following test program (adapted from samples/Querying/Querying.cpp) during the second iteration on EnumRows::Next(), if Table::Search() requests the binary field SE_ANNO_CAD_DATA

test_fgdb.cpp:

#include <string>
#include <iostream>
#include <fstream>

#include <FileGDBAPI.h>

using namespace std;
using namespace FileGDBAPI;

int main()
{
  // Open the geodatabase.
  fgdbError   hr;
  wstring     errorText;
  Geodatabase geodatabase;
  if ((hr = OpenGeodatabase(L"COASTS.gdb", geodatabase)) != S_OK)
  {
    wcout << "An error occurred while opening the geodatabase." << endl;
    ErrorInfo::GetErrorDescription(hr, errorText);
    wcout << errorText << "(" << hr << ")." << endl;
    return -1;
  }

  // Open the COAST_PROTECTION_STRUCT_LINE table.
  Table table;
  if ((hr = geodatabase.OpenTable(L"COAST_PROTECTION_STRUCT_LINE", table)) != S_OK)
  {
    wcout << "An error occurred while opening the table." << endl;
    ErrorInfo::GetErrorDescription(hr, errorText);
    wcout << errorText << "(" << hr << ")." << endl;
    return -1;
  }

  // Query
  EnumRows attrQueryRows;

  // Will crash on Next() iterations
  // Crashes on second Next() iteration if requesting the binary field SE_ANNO_CAD_DATA:
  wstring columns = L"OBJECTID, ASSET_ID, SE_ANNO_CAD_DATA";

  // Works fine if not requesting SE_ANNO_CAD_DATA:
  // wstring columns = L"OBJECTID, ASSET_ID, STRUCTURE_TYPE, CONSTRUCTION, LAST_MODIFIED, Shape_Length";

  if ((hr = table.Search(columns, L"", true, attrQueryRows)) != S_OK)
  {
    wcout << "An error occurred while performing the attribute query." << endl;
    ErrorInfo::GetErrorDescription(hr, errorText);
    wcout << errorText << "(" << hr << ")." << endl;
    return -1;
  }

  // Iterate through the returned rows.
  Row              attrQueryRow;
  // First iteration works, crash on second
  while (attrQueryRows.Next(attrQueryRow) == S_OK)
  {
      int assetId;
      attrQueryRow.GetInteger(L"ASSET_ID", assetId);
      int objectId;
      attrQueryRow.GetOID(objectId);
      wcout << objectId << "," << assetId << endl;
  }
  attrQueryRows.Close(); // Close the EnumRows

  return 0;
}

compile and run:

$ g++ test_fgdb.cpp -I/home/even/FileGDB_API-RHEL7-64gcc83/include -o test_fgdb -L/home/even/FileGDB_API-RHEL7-64gcc83/lib -lFileGDBAPI && ./test_fgdb 
286,101535
Segmentation fault (core dumped)

gdb traceback:

Thread 1 "test_fgdb" received signal SIGSEGV, Segmentation fault.
0x00007ffff6ee39c0 in SqlSelectCommand::CreateObjects() () from /home/even/FileGDB_API-RHEL7-64gcc83/lib/libFileGDBAPI.so
(gdb) bt
#0  0x00007ffff6ee39c0 in SqlSelectCommand::CreateObjects() () from /home/even/FileGDB_API-RHEL7-64gcc83/lib/libFileGDBAPI.so
#1  0x00007ffff6ee3dd4 in SqlSelectCommand::Next() () from /home/even/FileGDB_API-RHEL7-64gcc83/lib/libFileGDBAPI.so
#2  0x00007ffff6da969d in FileGDBAPI::EnumRows::Next(FileGDBAPI::Row&) () from /home/even/FileGDB_API-RHEL7-64gcc83/lib/libFileGDBAPI.so
#3  0x00005555555568dd in main ()

rouault avatar Feb 02 '22 16:02 rouault