• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

polserver / polserver / 21066490217

16 Jan 2026 12:22PM UTC coverage: 60.507%. Remained the same
21066490217

push

github

web-flow
misc clang-tidy (#853)

* trigger tidy

* Automated clang-tidy change: modernize-use-equals-delete,modernize-make-shared,modernize-make-unique,modernize-use-constraints,readability-container-size-empty,modernize-redundant-void-arg,modernize-use-emplace

* removed non needed macros

* missed to disable tidy build

---------

Co-authored-by: Clang Tidy <clang-tidy@users.noreply.github.com>

174 of 248 new or added lines in 74 files covered. (70.16%)

2 existing lines in 2 files now uncovered.

44459 of 73477 relevant lines covered (60.51%)

515895.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

47.84
/pol-core/pol/module/filemod.cpp
1
/** @file
2
 *
3
 * @par History
4
 * - 2005/04/31 Shinigami: mf_LogToFile - added flag to log Core-Style DateTimeStr in front of log
5
 * entry
6
 * - 2006/09/27 Shinigami: GCC 3.4.x fix - added "template<>" to TmplExecutorModule
7
 * - 2009/12/18 Turley:    added CreateDirectory() & ListDirectory()
8
 * - 2011/01/07 Nando:     mf_LogToFile - check the return of strftime
9
 */
10

11

12
#include <cerrno>
13
#include <ctime>
14
#include <filesystem>
15
#include <iosfwd>
16
#include <string>
17
#include <system_error>
18

19
#include "../../bscript/berror.h"
20
#include "../../bscript/bobject.h"
21
#include "../../bscript/impstr.h"
22
#include "../../clib/cfgelem.h"
23
#include "../../clib/cfgfile.h"
24
#include "../../clib/clib.h"
25
#include "../../clib/fileutil.h"
26
#include "../../clib/logfacility.h"
27
#include "../../clib/stlutil.h"
28
#include "../../plib/pkg.h"
29
#include "../binaryfilescrobj.h"
30
#include "../core.h"
31
#include "../globals/ucfg.h"
32
#include "../xmlfilescrobj.h"
33
#include "fileaccess.h"
34
#include "filemod.h"
35

36
#include <module_defs/file.h>
37

38
namespace Pol
39
{
40
namespace Module
41
{
42
using namespace Bscript;
43
namespace fs = std::filesystem;
44

45
/**
46
 * I'm thinking that, if anything, I'd want to present a VERY simple, high-level interface.
47
 *
48
 * So no seeking / reading / writing.  Something more like this:
49
 * - all filenames are package-relative.
50
 * - Only files in packages can be accessed.
51
 * - ReadFile( filename ); // returns the entire file as an array of lines
52
 * - WriteFile( filename, contents ); // writes a file in its entirely
53
 * - AppendToFile( filename, data );
54
 * - LogToFile( filename, text );
55
 *
56
 * WriteFile and AppendToFile would accept either a string or an array of lines.  The
57
 * string would be written verbatim, while the array of lines would be written with
58
 * newlines appended.
59
 *
60
 * WriteFile would be atomic for existing files - it would write a new file to a temporary
61
 * location, then do the rename-rename-delete thing.
62
 *
63
 * LogToFile would take a string as input, and append a newline.  It's the equivalent of
64
 * AppendToFile( filename, array { text } )
65
 *
66
 * Probably a systemwide configuration file would dictate the types of files allowed to
67
 * be written, and perhaps even name the packages allowed to do so.  I could see a
68
 * use for being able to write .src files, for example.  And I'm having thoughts of
69
 * integrating compile capability directly into pol, and adding something like
70
 * CompileScript( scriptpath ) to polsys.em
71
 *
72
 * config/fileaccess.cfg
73
 * ~~~~~~~~~~~~~~~~~~~~~
74
 * // anyone can append to a log file in their own package
75
 * FileAccess
76
 * {
77
 *   allow append
78
 *   match *.log
79
 *   package <all>
80
 * }
81
 * // anyone can create .htm files in their own web root
82
 * FileAccess
83
 * {
84
 *   allow write
85
 *   match www/ *.html
86
 *   package <all>
87
 * }
88
 * // the uploader package is allowed to write .src and .cfg files in any package
89
 * FileAccess
90
 * {
91
 *   allow read
92
 *   allow write
93
 *   remote 1
94
 *   match *.cfg
95
 *   match *.src
96
 *   package uploader
97
 * }
98
 * ~~~~~~~~~~~~~~~~~~~~~
99
 */
100
FileAccess::FileAccess( Clib::ConfigElem& elem )
2,022✔
101
    : AllowWrite( elem.remove_bool( "AllowWrite", false ) ),
2,022✔
102
      AllowAppend( elem.remove_bool( "AllowAppend", false ) ),
2,022✔
103
      AllowRead( elem.remove_bool( "AllowRead", false ) ),
2,022✔
104
      AllowRemote( elem.remove_bool( "AllowRemote", false ) ),
2,022✔
105
      AllPackages( false ),
2,022✔
106
      AllDirectories( false ),
2,022✔
107
      AllExtensions( false )
2,022✔
108
{
109
  std::string tmp;
2,022✔
110
  while ( elem.remove_prop( "Package", &tmp ) )
4,044✔
111
  {
112
    if ( tmp == "*" )
2,022✔
113
      AllPackages = true;
2,022✔
114
    else
115
    {
116
      auto pkg = Plib::find_package( tmp );
×
117
      if ( pkg == nullptr )
×
118
        ERROR_PRINTLN( "Fileaccess package entry not found: {}", tmp );
×
119
      else
120
        Packages.insert( pkg );
×
121
    }
122
    while ( elem.remove_prop( "Directory", &tmp ) )
4,044✔
123
    {
124
      if ( tmp == "*" )
2,022✔
125
        AllDirectories = true;
2,022✔
126
      else
127
      {
128
        const Plib::Package* cfgpkg;
129
        std::string cfgpath;
×
130
        if ( pkgdef_split( tmp, nullptr, &cfgpkg, &cfgpath ) )
×
NEW
131
          Directories.emplace_back( cfgpkg, cfgpath );
×
132
        else
133
          ERROR_PRINTLN( "Invalid fileaccess Directory entry: {}", tmp );
×
134
      }
×
135
    }
136
    if ( Directories.empty() )
2,022✔
137
      AllDirectories = true;
2,022✔
138
    while ( elem.remove_prop( "Extension", &tmp ) )
4,044✔
139
    {
140
      if ( tmp == "*" )
2,022✔
141
        AllExtensions = true;
2,022✔
142
      else
143
        Extensions.push_back( tmp );
×
144
    }
145
  }
146
}
2,022✔
147
bool FileAccess::AllowsAccessTo( const Plib::Package* pkg, const Plib::Package* filepackage ) const
172✔
148
{
149
  if ( AllowRemote )
172✔
150
    return true;
172✔
151

152
  if ( pkg == filepackage )
×
153
    return true;
×
154

155
  return false;
×
156
}
157

158
bool FileAccess::AppliesToPackage( const Plib::Package* pkg ) const
172✔
159
{
160
  if ( AllPackages )
172✔
161
    return true;
172✔
162

163
  if ( pkg == nullptr )
×
164
    return false;
×
165

166
  if ( Packages.count( pkg ) )
×
167
    return true;
×
168

169
  return false;
×
170
}
171

172
bool FileAccess::AppliesToPath( const std::string& path, const Plib::Package* filepkg ) const
172✔
173
{
174
  if ( !AllDirectories )
172✔
175
  {
176
    std::string filepath = path;
×
177
    if ( Clib::strip_one( filepath ) != 0 )
×
178
      filepath = "";
×
179

180
    bool found( false );
×
181
    for ( const auto& dir : Directories )
×
182
    {
183
      const auto& cfgpkg = dir.first;
×
184
      const auto& cfgpath = dir.second;
×
185
      if ( cfgpkg == filepkg )
×
186
      {
187
        if ( filepath.size() < cfgpath.size() )
×
188
        {
189
          found = false;
×
190
          continue;
×
191
        }
192
        found = true;
×
193
        for ( size_t i = 0; i < filepath.size() && i < cfgpath.size(); ++i )
×
194
        {
195
          if ( filepath[i] != cfgpath[i] )
×
196
          {
197
            found = false;
×
198
            break;
×
199
          }
200
        }
201
        if ( found )
×
202
          break;
×
203
      }
204
    }
205
    if ( !found )
×
206
      return false;
×
207
  }
×
208
  if ( AllExtensions )
172✔
209
    return true;
172✔
210

211
  // check for weirdness in the path
212
  if ( path.find( '\0' ) != std::string::npos )
×
213
    return false;
×
214
  if ( path.find( ".." ) != std::string::npos )
×
215
    return false;
×
216
  for ( const auto& ext : Extensions )
×
217
  {
218
    if ( path.size() >= ext.size() )
×
219
    {
220
      std::string path_ext = path.substr( path.size() - ext.size() );
×
221
      if ( Clib::stringicmp( path_ext, ext ) == 0 )
×
222
      {
223
        return true;
×
224
      }
225
    }
×
226
  }
227
  return false;
×
228
}
229

230
size_t FileAccess::estimateSize() const
1✔
231
{
232
  size_t size = sizeof( FileAccess );
1✔
233
  size += Clib::memsize( Packages );
1✔
234

235
  for ( const auto& d : Directories )
1✔
236
    size += sizeof( decltype( Directories )::value_type ) + d.second.capacity();
×
237
  for ( const auto& e : Extensions )
1✔
238
    size += e.capacity();
×
239
  return size;
1✔
240
}
241

242
bool HasReadAccess( const Plib::Package* pkg, const Plib::Package* filepackage,
131✔
243
                    const std::string& path )
244
{
245
  for ( const auto& fa : Core::configurationbuffer.file_access_rules )
131✔
246
  {
247
    if ( fa.AllowRead && fa.AllowsAccessTo( pkg, filepackage ) && fa.AppliesToPackage( pkg ) &&
262✔
248
         fa.AppliesToPath( path, filepackage ) )
131✔
249
    {
250
      return true;
131✔
251
    }
252
  }
253
  return false;
×
254
}
255
bool HasWriteAccess( const Plib::Package* pkg, const Plib::Package* filepackage,
41✔
256
                     const std::string& path )
257
{
258
  for ( const auto& fa : Core::configurationbuffer.file_access_rules )
41✔
259
  {
260
    if ( fa.AllowWrite && fa.AllowsAccessTo( pkg, filepackage ) && fa.AppliesToPackage( pkg ) &&
82✔
261
         fa.AppliesToPath( path, filepackage ) )
41✔
262
    {
263
      return true;
41✔
264
    }
265
  }
266
  return false;
×
267
}
268
bool HasAppendAccess( const Plib::Package* pkg, const Plib::Package* filepackage,
×
269
                      const std::string& path )
270
{
271
  for ( const auto& fa : Core::configurationbuffer.file_access_rules )
×
272
  {
273
    if ( fa.AllowAppend && fa.AllowsAccessTo( pkg, filepackage ) && fa.AppliesToPackage( pkg ) &&
×
274
         fa.AppliesToPath( path, filepackage ) )
×
275
    {
276
      return true;
×
277
    }
278
  }
279
  return false;
×
280
}
281

282
FileAccessExecutorModule::FileAccessExecutorModule( Bscript::Executor& exec )
2,356✔
283
    : TmplExecutorModule<FileAccessExecutorModule, Bscript::ExecutorModule>( exec )
2,356✔
284
{
285
}
2,356✔
286

287
ExecutorModule* CreateFileAccessExecutorModule( Executor& exec )
371✔
288
{
289
  return new FileAccessExecutorModule( exec );
371✔
290
}
291

292
Bscript::BObjectImp* FileAccessExecutorModule::mf_FileExists()
×
293
{
294
  const String* filename;
295
  if ( !getStringParam( 0, filename ) )
×
296
    return new BError( "Invalid parameter type." );
×
297

298
  const Plib::Package* outpkg;
299
  std::string path;
×
300
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
×
301
    return new BError( "Error in filename descriptor." );
×
302

303
  if ( path.find( ".." ) != std::string::npos )
×
304
    return new BError( "No parent path traversal allowed." );
×
305

306
  std::string filepath;
×
307
  if ( outpkg == nullptr )
×
308
    filepath = path;
×
309
  else
310
    filepath = outpkg->dir() + path;
×
311

312
  return new BLong( Clib::FileExists( filepath ) );
×
313
}
×
314

315
Bscript::BObjectImp* FileAccessExecutorModule::mf_ReadFile()
115✔
316
{
317
  const String* filename;
318
  if ( !getStringParam( 0, filename ) )
115✔
319
    return new BError( "Invalid parameter type" );
×
320

321
  const Plib::Package* outpkg;
322
  std::string path;
115✔
323
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
115✔
324
    return new BError( "Error in filename descriptor" );
×
325

326
  if ( path.find( ".." ) != std::string::npos )
115✔
327
    return new BError( "No parent path traversal please." );
×
328

329
  if ( !HasReadAccess( exec.prog()->pkg, outpkg, path ) )
115✔
330
    return new BError( "Access denied" );
×
331

332
  std::string filepath;
115✔
333
  if ( outpkg == nullptr )
115✔
334
    filepath = path;
104✔
335
  else
336
    filepath = outpkg->dir() + path;
11✔
337

338
  std::ifstream ifs( filepath.c_str() );
115✔
339
  if ( !ifs.is_open() )
115✔
340
    return new BError( "File not found: " + filepath );
×
341

342
  std::unique_ptr<Bscript::ObjArray> arr( new Bscript::ObjArray() );
115✔
343

344
  std::string line;
115✔
345
  bool first_line( true );
115✔
346
  while ( getline( ifs, line ) )
27,687✔
347
  {
348
    if ( first_line )
27,572✔
349
    {
350
      first_line = false;
115✔
351
      Clib::remove_bom( &line );
115✔
352
    }
353
    arr->addElement( new String( line, String::Tainted::YES ) );
27,572✔
354
  }
355

356
  return arr.release();
115✔
357
}
115✔
358

359
Bscript::BObjectImp* FileAccessExecutorModule::mf_WriteFile()
36✔
360
{
361
  const String* filename;
362
  Bscript::ObjArray* contents;
363
  if ( !getStringParam( 0, filename ) || !getObjArrayParam( 1, contents ) )
36✔
364
  {
365
    return new BError( "Invalid parameter type" );
2✔
366
  }
367
  const Plib::Package* outpkg;
368
  std::string path;
34✔
369
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
34✔
370
    return new BError( "Error in filename descriptor" );
×
371

372
  if ( path.find( ".." ) != std::string::npos )
34✔
373
    return new BError( "No parent path traversal please." );
×
374
  if ( !HasWriteAccess( exec.prog()->pkg, outpkg, path ) )
34✔
375
    return new BError( "Access denied" );
×
376

377
  std::string filepath;
34✔
378
  if ( outpkg == nullptr )
34✔
379
    filepath = path;
34✔
380
  else
381
    filepath = outpkg->dir() + path;
×
382

383
  std::string bakpath = filepath + ".bak";
34✔
384
  std::string tmppath = filepath + ".tmp";
34✔
385

386
  std::ofstream ofs( tmppath.c_str(), std::ios::out | std::ios::trunc );
34✔
387

388
  if ( !ofs.is_open() )
34✔
389
    return new BError( "File not found: " + filepath );
×
390

391
  for ( unsigned i = 0; i < contents->ref_arr.size(); ++i )
14,251✔
392
  {
393
    BObjectRef& ref = contents->ref_arr[i];
14,217✔
394
    BObject* obj = ref.get();
14,217✔
395
    if ( obj != nullptr )
14,217✔
396
    {
397
      ofs << ( *obj )->getStringRep();
14,217✔
398
    }
399
    ofs << std::endl;
14,217✔
400
  }
401
  if ( ofs.fail() )
34✔
402
    return new BError( "Error during write." );
×
403
  ofs.close();
34✔
404

405
  if ( Clib::FileExists( bakpath ) )
34✔
406
  {
407
    if ( unlink( bakpath.c_str() ) )
32✔
408
    {
409
      int err = errno;
×
410
      std::string message = "Unable to remove " + filepath + ": " + strerror( err );
×
411

412
      return new BError( message );
×
413
    }
×
414
  }
415
  if ( Clib::FileExists( filepath ) )
34✔
416
  {
417
    if ( rename( filepath.c_str(), bakpath.c_str() ) )
34✔
418
    {
419
      int err = errno;
×
420
      std::string message =
421
          "Unable to rename " + filepath + " to " + bakpath + ": " + strerror( err );
×
422
      return new BError( message );
×
423
    }
×
424
  }
425
  if ( rename( tmppath.c_str(), filepath.c_str() ) )
34✔
426
  {
427
    int err = errno;
×
428
    std::string message =
429
        "Unable to rename " + tmppath + " to " + filepath + ": " + strerror( err );
×
430
    return new BError( message );
×
431
  }
×
432

433
  return new BLong( 1 );
34✔
434
}
34✔
435

436
Bscript::BObjectImp* FileAccessExecutorModule::mf_AppendToFile()
×
437
{
438
  const String* filename;
439
  ObjArray* contents;
440
  if ( !getStringParam( 0, filename ) || !getObjArrayParam( 1, contents ) )
×
441
  {
442
    return new BError( "Invalid parameter type" );
×
443
  }
444

445
  const Plib::Package* outpkg;
446
  std::string path;
×
447
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
×
448
    return new BError( "Error in filename descriptor" );
×
449

450
  if ( path.find( ".." ) != std::string::npos )
×
451
    return new BError( "No parent path traversal please." );
×
452

453
  if ( !HasAppendAccess( exec.prog()->pkg, outpkg, path ) )
×
454
    return new BError( "Access denied" );
×
455

456
  std::string filepath;
×
457
  if ( outpkg == nullptr )
×
458
    filepath = path;
×
459
  else
460
    filepath = outpkg->dir() + path;
×
461

462
  std::ofstream ofs( filepath.c_str(), std::ios::out | std::ios::app );
×
463

464
  if ( !ofs.is_open() )
×
465
    return new BError( "Unable to open file: " + filepath );
×
466

467
  for ( unsigned i = 0; i < contents->ref_arr.size(); ++i )
×
468
  {
469
    BObjectRef& ref = contents->ref_arr[i];
×
470
    BObject* obj = ref.get();
×
471
    if ( obj != nullptr )
×
472
    {
473
      ofs << ( *obj )->getStringRep();
×
474
    }
475
    ofs << std::endl;
×
476
  }
477
  if ( ofs.fail() )
×
478
    return new BError( "Error during write." );
×
479

480
  return new BLong( 1 );
×
481
}
×
482

483
Bscript::BObjectImp* FileAccessExecutorModule::mf_LogToFile()
×
484
{  //
485
  const String* filename;
486
  const String* textline;
487
  if ( getStringParam( 0, filename ) && getStringParam( 1, textline ) )
×
488
  {
489
    int flags;
490
    if ( exec.fparams.size() >= 3 )
×
491
    {
492
      if ( !getParam( 2, flags ) )
×
493
        return new BError( "Invalid parameter type" );
×
494
    }
495
    else
496
    {
497
      flags = 0;
×
498
    }
499

500
    const Plib::Package* outpkg;
501
    std::string path;
×
502
    if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
×
503
      return new BError( "Error in filename descriptor" );
×
504

505
    if ( path.find( ".." ) != std::string::npos )
×
506
      return new BError( "No parent path traversal please." );
×
507

508
    if ( !HasAppendAccess( exec.prog()->pkg, outpkg, path ) )
×
509
      return new BError( "Access denied" );
×
510

511
    std::string filepath;
×
512
    if ( outpkg == nullptr )
×
513
      filepath = path;
×
514
    else
515
      filepath = outpkg->dir() + path;
×
516

517
    std::ofstream ofs( filepath.c_str(), std::ios::out | std::ios::app );
×
518

519
    if ( !ofs.is_open() )
×
520
      return new BError( "Unable to open file: " + filepath );
×
521

522
    if ( flags & Core::LOG_DATETIME )
×
523
    {
524
      auto time_tm = Clib::localtime( time( nullptr ) );
×
525

526
      char buffer[30];
527
      if ( strftime( buffer, sizeof buffer, "%m/%d %H:%M:%S", &time_tm ) > 0 )
×
528
        ofs << "[" << buffer << "] ";
×
529
    }
530

531
    ofs << textline->value() << std::endl;
×
532

533
    if ( ofs.fail() )
×
534
      return new BError( "Error during write." );
×
535

536
    return new BLong( 1 );
×
537
  }
×
538
  else
539
    return new BError( "Invalid parameter type" );
×
540
}
541

542
Bscript::BObjectImp* FileAccessExecutorModule::mf_OpenBinaryFile()
8✔
543
{
544
  const String* filename;
545
  unsigned short mode, bigendian;
546
  if ( ( !getStringParam( 0, filename ) ) || ( !getParam( 1, mode ) ) ||
16✔
547
       ( !getParam( 2, bigendian ) ) )
8✔
548
    return new BError( "Invalid parameter type" );
×
549

550
  const Plib::Package* outpkg;
551
  std::string path;
8✔
552
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
8✔
553
    return new BError( "Error in filename descriptor" );
×
554

555
  if ( path.find( ".." ) != std::string::npos )
8✔
556
    return new BError( "No parent path traversal please." );
×
557

558
  if ( mode & 0x01 )
8✔
559
  {
560
    if ( !HasReadAccess( exec.prog()->pkg, outpkg, path ) )
1✔
561
      return new BError( "Access denied" );
×
562
  }
563
  if ( mode & 0x02 )
8✔
564
  {
565
    if ( !HasWriteAccess( exec.prog()->pkg, outpkg, path ) )
7✔
566
      return new BError( "Access denied" );
×
567
  }
568

569
  std::string filepath;
8✔
570
  if ( outpkg == nullptr )
8✔
571
    filepath = path;
×
572
  else
573
    filepath = outpkg->dir() + path;
8✔
574

575
  return new Core::BBinaryfile( filepath, mode, bigendian == 1 ? true : false );
8✔
576
}
8✔
577

578
Bscript::BObjectImp* FileAccessExecutorModule::mf_CreateDirectory()
×
579
{
580
  const String* dirname;
581
  if ( !getStringParam( 0, dirname ) )
×
582
    return new BError( "Invalid parameter type" );
×
583

584
  const Plib::Package* outpkg;
585
  std::string path;
×
586
  if ( !pkgdef_split( dirname->value(), exec.prog()->pkg, &outpkg, &path ) )
×
587
    return new BError( "Error in dirname descriptor" );
×
588
  if ( path.find( ".." ) != std::string::npos )
×
589
    return new BError( "No parent path traversal please." );
×
590

591
  if ( outpkg != nullptr )
×
592
    path = outpkg->dir() + path;
×
593
  path = Clib::normalized_dir_form( path );
×
594
  if ( Clib::IsDirectory( path.c_str() ) )
×
595
    return new BError( "Directory already exists." );
×
596
  int res = Clib::make_dir( path.c_str() );
×
597
  if ( res != 0 )
×
598
    return new BError( "Could not create directory." );
×
599
  return new BLong( 1 );
×
600
}
×
601

602
Bscript::BObjectImp* FileAccessExecutorModule::mf_ListDirectory()
18✔
603
{
604
  const String* dirname;
605
  const String* extension;
606
  short listdirs;
607
  if ( ( !getStringParam( 0, dirname ) ) || ( !getStringParam( 1, extension ) ) ||
36✔
608
       ( !getParam( 2, listdirs ) ) )
18✔
609
    return new BError( "Invalid parameter type" );
×
610

611
  const Plib::Package* outpkg;
612
  std::string path;
18✔
613
  if ( !pkgdef_split( dirname->value(), exec.prog()->pkg, &outpkg, &path ) )
18✔
614
    return new BError( "Error in dirname descriptor" );
×
615
  if ( path.find( ".." ) != std::string::npos )
18✔
616
    return new BError( "No parent path traversal please." );
×
617

618
  if ( outpkg != nullptr )
18✔
619
    path = outpkg->dir() + path;
18✔
620
  path = Clib::normalized_dir_form( path );
18✔
621
  if ( !Clib::IsDirectory( path.c_str() ) )
18✔
622
    return new BError( "Directory not found." );
×
623
  bool asterisk = false;
18✔
624
  bool nofiles = false;
18✔
625
  std::string ext_s = extension->value();
18✔
626
  if ( ext_s.find( '*', 0 ) != std::string::npos )
18✔
627
    asterisk = true;
×
628
  else if ( ext_s.empty() )
18✔
629
    nofiles = true;
×
630
  else if ( *ext_s.begin() != '.' )
18✔
631
    ext_s.insert( 0, "." );
18✔
632

633

634
  Bscript::ObjArray* arr = new Bscript::ObjArray;
18✔
635
  std::error_code ec;
18✔
636
  for ( const auto& dir_entry : fs::directory_iterator( path, ec ) )
850✔
637
  {
638
    if ( auto fn = dir_entry.path().filename().string(); !fn.empty() && *fn.begin() == '.' )
416✔
639
      continue;
416✔
640
    if ( dir_entry.is_directory() )
415✔
641
    {
642
      if ( listdirs == 0 )
4✔
643
        continue;
4✔
644
    }
645
    else if ( nofiles )
411✔
646
      continue;
×
647
    else if ( !asterisk )
411✔
648
    {
649
      if ( dir_entry.path().extension().compare( ext_s ) != 0 )
411✔
650
        continue;
285✔
651
    }
652

653
    arr->addElement( new String( dir_entry.path().filename().string() ) );
126✔
654
  }
18✔
655

656
  return arr;
18✔
657
}
18✔
658

659
Bscript::BObjectImp* FileAccessExecutorModule::mf_OpenXMLFile()
15✔
660
{
661
  const String* filename;
662
  if ( !getStringParam( 0, filename ) )
15✔
663
    return new BError( "Invalid parameter type" );
×
664

665
  const Plib::Package* outpkg;
666
  std::string path;
15✔
667
  if ( !pkgdef_split( filename->value(), exec.prog()->pkg, &outpkg, &path ) )
15✔
668
    return new BError( "Error in filename descriptor" );
×
669

670
  if ( path.find( ".." ) != std::string::npos )
15✔
671
    return new BError( "No parent path traversal please." );
×
672

673
  if ( !HasReadAccess( exec.prog()->pkg, outpkg, path ) )
15✔
674
    return new BError( "Access denied" );
×
675

676
  std::string filepath;
15✔
677
  if ( outpkg == nullptr )
15✔
678
    filepath = path;
15✔
679
  else
680
    filepath = outpkg->dir() + path;
×
681
  if ( !Clib::FileExists( filepath ) )
15✔
682
    return new BError( "File does not exist" );
3✔
683
  std::unique_ptr<Core::BXMLfile> xml( new Core::BXMLfile( filepath ) );
12✔
684
  if ( !xml->isTrue() )
12✔
685
    return new BError( xml->getStringRep() );
3✔
686
  return xml.release();
9✔
687
}
15✔
688

689
Bscript::BObjectImp* FileAccessExecutorModule::mf_CreateXMLFile()
×
690
{
691
  return new Core::BXMLfile();
×
692
}
693

694
void load_fileaccess_cfg()
2,022✔
695
{
696
  Core::configurationbuffer.file_access_rules.clear();
2,022✔
697

698
  if ( !Clib::FileExists( "config/fileaccess.cfg" ) )
2,022✔
699
    return;
×
700

701
  Clib::ConfigFile cf( "config/fileaccess.cfg", "FileAccess" );
2,022✔
702
  Clib::ConfigElem elem;
2,022✔
703

704

705
  while ( cf.read( elem ) )
4,044✔
706
  {
707
    FileAccess fa( elem );
2,022✔
708
    Core::configurationbuffer.file_access_rules.push_back( fa );
2,022✔
709
  }
2,022✔
710
}
2,022✔
711
}  // namespace Module
712
}  // namespace Pol
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc