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

polserver / polserver / 21100551564

17 Jan 2026 08:40PM UTC coverage: 60.504% (+0.01%) from 60.492%
21100551564

Pull #857

github

turleypol
fixed scope
Pull Request #857: ClangTidy readability-else-after-return

837 of 1874 new or added lines in 151 files covered. (44.66%)

48 existing lines in 26 files now uncovered.

44445 of 73458 relevant lines covered (60.5%)

515341.61 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

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

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

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

154
  return false;
×
155
}
156

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

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

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

168
  return false;
×
169
}
170

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

535
    return new BLong( 1 );
×
536
  }
×
NEW
537
  return new BError( "Invalid parameter type" );
×
538
}
539

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

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

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

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

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

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

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

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

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

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

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

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

631

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

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

654
  return arr;
18✔
655
}
18✔
656

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

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

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

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

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

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

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

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

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

702

703
  while ( cf.read( elem ) )
4,044✔
704
  {
705
    FileAccess fa( elem );
2,022✔
706
    Core::configurationbuffer.file_access_rules.push_back( fa );
2,022✔
707
  }
2,022✔
708
}
2,022✔
709
}  // namespace Pol::Module
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