Skip to content

Commit

Permalink
- fixed BiblioSpec DiaNN parser to support mass-only mods (#3173)
Browse files Browse the repository at this point in the history
* fixed BlibException to avoid potential buffer overruns by switching to boost::format
- verified by Fengchao Yu
  • Loading branch information
chambm authored Oct 9, 2024
1 parent 5b26d91 commit 2f9a56f
Show file tree
Hide file tree
Showing 8 changed files with 1,314 additions and 24 deletions.
50 changes: 31 additions & 19 deletions pwiz_tools/BiblioSpec/src/BlibException.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,48 @@
* decide what to add to the string.
*/

#include <cstdarg>
#include <cstdio>
#include <exception>
#include <string>
#include <boost/format.hpp>

namespace BiblioSpec{

class BlibException : public std::exception{
protected:
std::string msgStr_;
bool hasFilename_;


static std::string formatStringForward(boost::format& message)
{
return message.str();
}

template <typename TValue, typename... TArgs>
std::string formatStringForward(boost::format& message, TValue&& arg, TArgs&&... args)
{
message % std::forward<TValue>(arg);
return formatStringForward(message, std::forward<TArgs>(args)...);
}

public:
BlibException()
: hasFilename_(false)
{
msgStr_ = "BiblioSpec exception thrown.";
}

BlibException(bool filename, const char* format, ...)

template <typename... TArgs>
BlibException(bool filename, const char* format, TArgs&&... args)
: hasFilename_(filename)
{
va_list args;
va_start(args, format);
char buffer[4096];

vsprintf(buffer, format, args);
msgStr_ = buffer;
boost::format message(format);
msgStr_ = formatStringForward(message, std::forward<TArgs>(args)...);
}

BlibException(bool filename, const std::string& message)
: hasFilename_(filename)
{
msgStr_ = message;
}

~BlibException()throw(){}
Expand All @@ -63,17 +77,15 @@ namespace BiblioSpec{
hasFilename_ = hasIt;
}

virtual bool hasFilename(){
virtual bool hasFilename(){
return hasFilename_;
}

virtual void addMessage(const char* format, ...){
va_list args;
va_start(args, format);
char buffer[4096];

vsprintf(buffer, format, args);
msgStr_ += buffer;
template <typename... TArgs>
void addMessage(const char* format, TArgs&&... args)
{
boost::format message(format);
msgStr_ += formatStringForward(message, std::forward<TArgs>(args)...);
}

virtual const char* what() const throw()
Expand Down
2 changes: 1 addition & 1 deletion pwiz_tools/BiblioSpec/src/BuildParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ void BuildParser::setSpecFileName(
if( curSpecFileName_.empty() ) {
string extString = fileNotFoundMessage(specfileroot,
extensions, localDirectories);
throw BlibException(true, extString.c_str());
throw BlibException(true, extString);
}// else we found a file and set the name

Verbosity::comment(V_DETAIL, "spectrum filename set to %s", curSpecFileName_.c_str());
Expand Down
20 changes: 17 additions & 3 deletions pwiz_tools/BiblioSpec/src/DiaNNSpecLibReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "pwiz/data/common/Unimod.hpp"
#include "libraries/csv.h"
#include <boost/type_index.hpp>
#include <pwiz/data/proteome/AminoAcid.hpp>

namespace BiblioSpec
{
Expand Down Expand Up @@ -184,14 +185,27 @@ inline std::string get_aas(const std::string &name, vector<SeqMod>& mods)
if (symbol < 'A' || symbol > 'Z') {
if (symbol != '(' && symbol != '[') continue;
end = closing_bracket(name, symbol, i);
int position = max(1, static_cast<int>(j));

if (name.find("(UniMod:", i, modPrefixLength) != i)
throw std::runtime_error("unable to handle mod in library entry: " + name);
{
string potentialMass = name.substr(i + 1, end - i - 1);
if (potentialMass.find_first_not_of("01234567890.") != string::npos)
throw std::runtime_error("unable to handle mod in library entry as either a UniMod id or delta mass: " + potentialMass + " in " + name);
double modMass = lexical_cast<double>(potentialMass);
if (i > 0)
modMass -= pwiz::proteome::AminoAcid::Info::record(name[i - 1]).residueFormula.monoisotopicMass();

if (!mods.empty() && mods.back().position == position)
mods.back().deltaMass += modMass;
else
mods.emplace_back(position, modMass);
continue;
}

i += modPrefixLength;
mod = name.substr(i, end-i);
mod = name.substr(i, end - i);
CVID unimodCvid = (CVID) (UNIMOD_unimod_root_node + lexical_cast<int>(mod));
int position = max(1, static_cast<int>(j));
if (!mods.empty() && mods.back().position == position)
mods.back().deltaMass += unimod::modification(unimodCvid).deltaMonoisotopicMass();
else
Expand Down
2 changes: 1 addition & 1 deletion pwiz_tools/BiblioSpec/src/saxhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool SAXHandler::parse()
if (!success) {
string error = generateError(message.empty() ? getParserError() : message);
Verbosity::debug(error.c_str());
throw BlibException(true, error.c_str());
throw BlibException(true, error);
}

return true;
Expand Down
1 change: 1 addition & 0 deletions pwiz_tools/BiblioSpec/tests/Jamfile.jam
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ blib-test-build metamorpheus-mzid : --unicode -o : output/metamorpheus.blib : me
blib-test-build diann-speclib : -o : output/diann-speclib.blib : diann-speclib.check : $(TEST_INPUTS_PATH)/diann-swath.speclib ;
blib-test-build diann-speclib-diapasef : -o : output/diann-hela-diapasef.blib : diann-hela-diapasef.check : $(TEST_INPUTS_PATH)/diann-hela-diapasef-lib.speclib ;
blib-test-build-basic diann-mod-test : -o : $(TEST_INPUTS_PATH)/diann-mod-test.tsv.speclib ;
blib-test-build-basic diann-mass-mod-test : -o : $(TEST_INPUTS_PATH)/diann-mass-mods.tsv.speclib ;
blib-test-build-basic msfragger-diann : -o : $(TEST_INPUTS_PATH)/library.tsv.speclib ;
blib-test-build-basic msfragger-diann-predicted : -o : $(TEST_INPUTS_PATH)/diann-predicted/lib.predicted.speclib ;

Expand Down
Loading

0 comments on commit 2f9a56f

Please sign in to comment.