Skip to content

Commit 8913b06

Browse files
authored
Fix #408: Parser can blow up if no [preset00] header (#450)
* Fix: Parser can blow up if no [preset00] header * fix no debug mode * Remove assert that is blowing up because it looks like this is sort of handled. * Only do rdft() on powers of 2 samples * Only do rdft() on powers of 2 samples * Revert changes to PCM.cpp sampling, needs more thoughtful fixing
1 parent 67a1999 commit 8913b06

File tree

7 files changed

+58
-33
lines changed

7 files changed

+58
-33
lines changed

Diff for: bad_presets.tar

-1.39 MB
Binary file not shown.

Diff for: configure.ac

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
AC_INIT([projectM], [3.1.9], [[email protected]], [projectM], [https://github.com/projectM-visualizer/projectm/])
1+
AC_INIT([projectM], [3.1.10], [[email protected]], [projectM], [https://github.com/projectM-visualizer/projectm/])
22
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects tar-pax])
33

4+
AX_IS_RELEASE([git-directory])
5+
AX_CHECK_ENABLE_DEBUG([no], [DEBUG])
6+
47
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
58
LT_INIT
69

Diff for: src/libprojectM/FileScanner.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ std::string FileScanner::extensionMatches(std::string &filename) {
7575
return {};
7676
}
7777

78+
bool FileScanner::isValidFilename(std::string &filename) {
79+
if (filename.find("__MACOSX") != std::string::npos) return false;
80+
return true;
81+
}
7882

7983
// generic implementation using dirent
8084
void FileScanner::scanGeneric(ScanCallback cb, const char *currentDir) {
@@ -93,6 +97,8 @@ void FileScanner::scanGeneric(ScanCallback cb, const char *currentDir) {
9397
// Convert char * to friendly string
9498
std::string filename(dir_entry->d_name);
9599

100+
// Some sanity checks
101+
if (! isValidFilename(filename)) continue;
96102
if (filename.length() > 0 && filename[0] == '.')
97103
continue;
98104

@@ -165,6 +171,8 @@ void FileScanner::scanPosix(ScanCallback cb) {
165171
path = std::string(node->fts_path);
166172
name = std::string(node->fts_name);
167173

174+
if (!isValidFilename(path) || !isValidFilename(name)) break;
175+
168176
// check extension
169177
nameMatched = extensionMatches(name);
170178
if (! nameMatched.empty())

Diff for: src/libprojectM/FileScanner.hpp

+13-12
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,25 @@ extern "C"
2525
#include "dirent.h"
2626
#endif
2727

28-
typedef std::function<void (std::string &path, std::string &name)> ScanCallback;
28+
typedef std::function<void(std::string &path, std::string &name)> ScanCallback;
2929

30-
class FileScanner {
30+
class FileScanner
31+
{
3132
public:
32-
FileScanner();
33-
FileScanner(std::vector<std::string> &rootDirs, std::vector<std::string> &extensions);
33+
FileScanner();
34+
FileScanner(std::vector<std::string> &rootDirs, std::vector<std::string> &extensions);
3435

35-
void scan(ScanCallback cb);
36-
std::string extensionMatches(std::string &filename);
36+
void scan(ScanCallback cb);
37+
std::string extensionMatches(std::string &filename);
3738

3839
private:
39-
std::vector<std::string> _rootDirs;
40-
std::vector<std::string> _extensions;
40+
std::vector<std::string> _rootDirs;
41+
std::vector<std::string> _extensions;
4142

42-
void scanGeneric(ScanCallback cb, const char *dir);
43-
void scanPosix(ScanCallback cb);
44-
void handleDirectoryError(std::string dir);
43+
void scanGeneric(ScanCallback cb, const char *dir);
44+
void scanPosix(ScanCallback cb);
45+
void handleDirectoryError(std::string dir);
46+
bool isValidFilename(std::string &filename);
4547
};
4648

47-
4849
#endif /* FileScanner_hpp */

Diff for: src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp

+16-15
Original file line numberDiff line numberDiff line change
@@ -459,25 +459,26 @@ int MilkdropPreset::readIn(std::istream & fs) {
459459
presetOutputs().compositeShader.programSource.clear();
460460
presetOutputs().warpShader.programSource.clear();
461461

462-
/* Parse any comments */
463-
if (Parser::parse_top_comment(fs) < 0)
462+
/* Parse any comments (aka "[preset00]") */
463+
/* We don't do anything with this info so it's okay if it's missing */
464+
if (Parser::parse_top_comment(fs) == PROJECTM_SUCCESS)
464465
{
466+
/* Parse the preset name and a left bracket */
467+
char tmp_name[MAX_TOKEN_SIZE];
468+
469+
if (Parser::parse_preset_name(fs, tmp_name) < 0)
470+
{
471+
std::cerr << "[Preset::readIn] loading of preset name failed" << std::endl;
472+
fs.seekg(0);
473+
}
474+
/// @note We ignore the preset name because [preset00] is just not so useful
475+
} else {
476+
// no comment found. whatever
465477
if (MILKDROP_PRESET_DEBUG)
466-
std::cerr << "[Preset::readIn] no left bracket found..." << std::endl;
467-
return PROJECTM_FAILURE;
468-
}
469-
470-
/* Parse the preset name and a left bracket */
471-
char tmp_name[MAX_TOKEN_SIZE];
472-
473-
if (Parser::parse_preset_name(fs, tmp_name) < 0)
474-
{
475-
std::cerr << "[Preset::readIn] loading of preset name failed" << std::endl;
476-
return PROJECTM_ERROR;
478+
std::cerr << "[Preset::readIn] no left bracket found..." << std::endl;
479+
fs.seekg(0);
477480
}
478481

479-
/// @note We ignore the preset name because [preset00] is just not so useful
480-
481482
// Loop through each line in file, trying to successfully parse the file.
482483
// If a line does not parse correctly, keep trucking along to next line.
483484
int retval;

Diff for: src/libprojectM/MilkdropPresetFactory/MilkdropPreset.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,12 @@
3535
#include <cassert>
3636
#include <map>
3737

38-
#define MILKDROP_PRESET_DEBUG 0 /* 0 for no debugging, 1 for normal, 2 for insane */
38+
#ifdef DEBUG
39+
/* 0 for no debugging, 1 for normal, 2 for insane */
40+
#define MILKDROP_PRESET_DEBUG 1
41+
#else
42+
#define MILKDROP_PRESET_DEBUG 0
43+
#endif
3944

4045
#include "CustomShape.hpp"
4146
#include "CustomWave.hpp"

Diff for: src/libprojectM/MilkdropPresetFactory/Parser.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,13 @@ token_t Parser::parseToken(std::istream & fs, char * string)
9090

9191
last_token_size++;
9292
/* If the string line buffer is full, quit */
93-
if (string_line_buffer_index == (STRING_LINE_SIZE - 1))
94-
return tStringBufferFilled;
93+
if (string_line_buffer_index == (STRING_LINE_SIZE - 1)) {
94+
if (PARSE_DEBUG) {
95+
string_line_buffer[string_line_buffer_index++] = '\0';
96+
std::cout << "ERROR String line buffer full. Buffer: " << string_line_buffer << std::endl;
97+
}
98+
return tStringBufferFilled;
99+
}
95100

96101
/* Otherwise add this character to the string line buffer */
97102
string_line_buffer[string_line_buffer_index++] = tolower(c);
@@ -119,6 +124,7 @@ token_t Parser::parseToken(std::istream & fs, char * string)
119124
c = EOF;
120125
else
121126
c = fs.get();
127+
std::cout << "parsing comment, c=" << c << std::endl;
122128
if (c == EOF)
123129
{
124130
line_mode = UNSET_LINE_MODE;
@@ -301,8 +307,9 @@ int Parser::parse_top_comment(std::istream & fs)
301307
/* Process tokens until left bracket is found */
302308
while ((token = parseToken(fs, string)) != tLBr)
303309
{
304-
if (token == tEOF)
305-
return PROJECTM_PARSE_ERROR;
310+
if (token == tEOF || token == tStringBufferFilled)
311+
// filled up the buffer and didn't find a '['
312+
return PROJECTM_PARSE_ERROR;
306313
}
307314

308315
/* Done, return success */

0 commit comments

Comments
 (0)