diff --git a/modules/io/src/mol/pdb_writer.cc b/modules/io/src/mol/pdb_writer.cc index d06a5228c5890f593c40c86ac9ceb4617f6ee379..6ce7df41b732ebfa883c357ad771f0dc5b055676 100644 --- a/modules/io/src/mol/pdb_writer.cc +++ b/modules/io/src/mol/pdb_writer.cc @@ -67,6 +67,15 @@ bool shift_left(const String& atom_name, bool is_hetatm, element=="MG" || element=="LI"); } + +bool atom_pos_ok(geom::Vec3 p) { + for (int i=0; i<3; ++i) { + if (p[i]<=-1000 || p[i] >= 10000) { + return false; + } + } + return true; +} void write_atom(std::ostream& ostr, FormattedLine& line, const mol::AtomHandle& atom, int atomnum, bool is_pqr, bool charmm_style) @@ -130,6 +139,9 @@ void write_atom(std::ostream& ostr, FormattedLine& line, // deal with alternative atom locations if (names.empty()) { + if (!atom_pos_ok(p)) { + throw IOException("Atom position outside of bounds supported by PDB format"); + } line(30, 8)=fmt::LPaddedFloat(p[0], 3); line(38, 8)=fmt::LPaddedFloat(p[1], 3); line(46, 8)=fmt::LPaddedFloat(p[2], 3); @@ -158,6 +170,9 @@ void write_atom(std::ostream& ostr, FormattedLine& line, p=geom::Vec3(tf*geom::Vec4(atom.GetAltPos(*i))); line(30, 50).Clear(); + if (!atom_pos_ok(p)) { + throw IOException("Atom position outside of bounds supported by PDB format"); + } if (i->size()>1) { throw IOException("Alternative atom indicator '"+atom.GetQualifiedName()+ "("+*i+")' too long for PDB output. At most 1 " diff --git a/modules/io/tests/test_io_pdb.cc b/modules/io/tests/test_io_pdb.cc index b0e54cdc37dacf167da076cc78b813c2ee7b4fab..f2aa055fbe397295fa6bd5449ea16dd351482573 100644 --- a/modules/io/tests/test_io_pdb.cc +++ b/modules/io/tests/test_io_pdb.cc @@ -1029,6 +1029,24 @@ BOOST_AUTO_TEST_CASE(test_pqr_read_atom) BOOST_CHECK_CLOSE(a2.GetRadius(), Real(1.7503), Real(1e-4)); } +BOOST_AUTO_TEST_CASE(checks_for_atom_pos_overflow) +{ + std::stringstream out; + PDBWriter writer(out, IOProfile()); + writer.SetIsPQR(true); + + mol::EntityHandle ent=mol::CreateEntity(); + mol::XCSEditor edi=ent.EditXCS(); + mol::ChainHandle ch=edi.InsertChain("A"); + mol::ResidueHandle r=edi.AppendResidue(ch, "GLY"); + + mol::AtomHandle a=edi.InsertAtom(r, "CA", geom::Vec3(0, -1000,0), "C"); + + BOOST_CHECK_THROW(writer.Write(ent), IOException); + edi.SetAtomPos(a, geom::Vec3(10000,0,0)); + BOOST_CHECK_THROW(writer.Write(ent), IOException); +} + BOOST_AUTO_TEST_CASE(test_pqr_write_atom) { std::stringstream out;