Commit 2a7d2dee authored by Axel Kohlmeyer's avatar Axel Kohlmeyer
Browse files

add more strict checking of data when parsing molecule files to detect format errors

parent f68c6254
Loading
Loading
Loading
Loading
+213 −220
Original line number Diff line number Diff line
@@ -427,47 +427,61 @@ void Molecule::read(int flag)

    // search line for header keywords and set corresponding variable

    if (strstr(line,"atoms")) sscanf(line,"%d",&natoms);
    else if (strstr(line,"bonds")) sscanf(line,"%d",&nbonds);
    else if (strstr(line,"angles")) sscanf(line,"%d",&nangles);
    else if (strstr(line,"dihedrals")) sscanf(line,"%d",&ndihedrals);
    else if (strstr(line,"impropers")) sscanf(line,"%d",&nimpropers);

    else if (strstr(line,"mass")) {
    int nmatch = 0;
    int nwant = 0;
    if (strstr(line,"atoms")) {
      nmatch = sscanf(line,"%d",&natoms);
      nwant = 1;
    } else if (strstr(line,"bonds")) {
      nmatch = sscanf(line,"%d",&nbonds);
      nwant = 1;
    } else if (strstr(line,"angles")) {
      nmatch = sscanf(line,"%d",&nangles);
      nwant = 1;
    } else if (strstr(line,"dihedrals")) {
      nmatch = sscanf(line,"%d",&ndihedrals);
      nwant = 1;
    } else if (strstr(line,"impropers")) {
      nmatch = sscanf(line,"%d",&nimpropers);
      nwant = 1;
    } else if (strstr(line,"mass")) {
      massflag = 1;
      sscanf(line,"%lg",&masstotal);
      nmatch = sscanf(line,"%lg",&masstotal);
      nwant = 1;
      masstotal *= sizescale*sizescale*sizescale;
    }
    else if (strstr(line,"com")) {
    } else if (strstr(line,"com")) {
      comflag = 1;
      sscanf(line,"%lg %lg %lg",&com[0],&com[1],&com[2]);
      nmatch = sscanf(line,"%lg %lg %lg",&com[0],&com[1],&com[2]);
      nwant = 3;
      com[0] *= sizescale;
      com[1] *= sizescale;
      com[2] *= sizescale;
      if (domain->dimension == 2 && com[2] != 0.0)
        error->all(FLERR,"Molecule file z center-of-mass must be 0.0 for 2d");
    }
    else if (strstr(line,"inertia")) {
    } else if (strstr(line,"inertia")) {
      inertiaflag = 1;
      sscanf(line,"%lg %lg %lg %lg %lg %lg",
      nmatch = sscanf(line,"%lg %lg %lg %lg %lg %lg",
                      &itensor[0],&itensor[1],&itensor[2],
                      &itensor[3],&itensor[4],&itensor[5]);
      itensor[0] *= sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[1] *= sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[2] *= sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[3] *= sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[4] *= sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[5] *= sizescale*sizescale*sizescale*sizescale*sizescale;
    }
    else if (strstr(line,"body")) {
      nwant = 6;
      const double scale5 = sizescale*sizescale*sizescale*sizescale*sizescale;
      itensor[0] *= scale5;
      itensor[1] *= scale5;
      itensor[2] *= scale5;
      itensor[3] *= scale5;
      itensor[4] *= scale5;
      itensor[5] *= scale5;
    } else if (strstr(line,"body")) {
      bodyflag = 1;
      avec_body = (AtomVecBody *) atom->style_match("body");
      if (!avec_body) 
        error->all(FLERR,"Molecule file requires atom style body");
      sscanf(line,"%d %d",&nibody,&ndbody);
    }
      nmatch = sscanf(line,"%d %d",&nibody,&ndbody);
      nwant = 2;
    } else break;

    else break;
    if (nmatch != nwant)
      error->all(FLERR,"Invalid header in molecule file");
  }

  // error checks
@@ -493,7 +507,7 @@ void Molecule::read(int flag)

  // loop over sections of molecule file

  while (strlen(keyword)) {
  while (strlen(keyword) > 0) {
    if (strcmp(keyword,"Coords") == 0) {
      xflag = 1;
      if (flag) coords(line);
@@ -641,12 +655,9 @@ void Molecule::coords(char *line)
  int tmp;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 4)
    if (4 != sscanf(line,"%d %lg %lg %lg",&tmp,&x[i][0],&x[i][1],&x[i][2]))
      error->all(FLERR,"Invalid Coords section in molecule file");
    }
    sscanf(line,"%d %lg %lg %lg",&tmp,&x[i][0],&x[i][1],&x[i][2]);

    x[i][0] *= sizescale;
    x[i][1] *= sizescale;
    x[i][2] *= sizescale;
@@ -669,12 +680,8 @@ void Molecule::types(char *line)
  int tmp;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 2)
    if (2 != sscanf(line,"%d %d",&tmp,&type[i]))
      error->all(FLERR,"Invalid Types section in molecule file");
    }
    sscanf(line,"%d %d",&tmp,&type[i]);
    type[i] += toffset;
  }

@@ -695,13 +702,9 @@ void Molecule::charges(char *line)
  int tmp;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 2)
    if (2 != sscanf(line,"%d %lg",&tmp,&q[i]))
      error->all(FLERR,"Invalid Charges section in molecule file");
  }
    sscanf(line,"%d %lg",&tmp,&q[i]);
  }
}

/* ----------------------------------------------------------------------
@@ -714,12 +717,8 @@ void Molecule::diameters(char *line)
  maxradius = 0.0;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 2)
    if (2 != sscanf(line,"%d %lg",&tmp,&radius[i]))
      error->all(FLERR,"Invalid Diameters section in molecule file");
    }
    sscanf(line,"%d %lg",&tmp,&radius[i]);
    radius[i] *= sizescale;
    radius[i] *= 0.5;
    maxradius = MAX(maxradius,radius[i]);
@@ -739,12 +738,8 @@ void Molecule::masses(char *line)
  int tmp;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 2)
    if (2 != sscanf(line,"%d %lg",&tmp,&rmass[i]))
      error->all(FLERR,"Invalid Masses section in molecule file");
    }
    sscanf(line,"%d %lg",&tmp,&rmass[i]);
    rmass[i] *= sizescale*sizescale*sizescale;
  }

@@ -773,13 +768,9 @@ void Molecule::bonds(int flag, char *line)

  for (int i = 0; i < nbonds; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 4)
    if (4 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT,
           &tmp,&itype,&atom1,&atom2))
      error->all(FLERR,"Invalid Bonds section in molecule file");
    }
    sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT,
           &tmp,&itype,&atom1,&atom2);
    itype += boffset;

    if (atom1 <= 0 || atom1 > natoms ||
@@ -835,13 +826,9 @@ void Molecule::angles(int flag, char *line)

  for (int i = 0; i < nangles; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 5)
    if (5 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
           &tmp,&itype,&atom1,&atom2,&atom3))
      error->all(FLERR,"Invalid Angles section in molecule file");
    }
    sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
           &tmp,&itype,&atom1,&atom2,&atom3);
    itype += aoffset;

    if (atom1 <= 0 || atom1 > natoms ||
@@ -911,14 +898,10 @@ void Molecule::dihedrals(int flag, char *line)

  for (int i = 0; i < ndihedrals; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 6)
        error->all(FLERR,"Invalid Dihedrals section in molecule file");
    }
    sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " "
    if (6 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " "
           TAGINT_FORMAT " " TAGINT_FORMAT " ",
           &tmp,&itype,&atom1,&atom2,&atom3,&atom4);
           &tmp,&itype,&atom1,&atom2,&atom3,&atom4))
      error->all(FLERR,"Invalid Dihedrals section in molecule file");
    itype += doffset;

    if (atom1 <= 0 || atom1 > natoms ||
@@ -1002,14 +985,10 @@ void Molecule::impropers(int flag, char *line)

  for (int i = 0; i < nimpropers; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 6)
        error->all(FLERR,"Invalid Impropers section in molecule file");
    }
    sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " "
    if (6 != sscanf(line,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " "
           TAGINT_FORMAT " " TAGINT_FORMAT " ",
           &tmp,&itype,&atom1,&atom2,&atom3,&atom4);
           &tmp,&itype,&atom1,&atom2,&atom3,&atom4))
      error->all(FLERR,"Invalid Impropers section in molecule file");
    itype += ioffset;

    if (atom1 <= 0 || atom1 > natoms ||
@@ -1087,13 +1066,9 @@ void Molecule::nspecial_read(int flag, char *line)

  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (i == 0) {
      int nwords = atom->count_words(line);
      if (nwords != 4)
    if (4 != sscanf(line,"%d %d %d %d",&tmp,&c1,&c2,&c3))
      error->all(FLERR,"Invalid Special Bond Counts section in "
                 "molecule file");
    }
    sscanf(line,"%d %d %d %d",&tmp,&c1,&c2,&c3);

    if (flag) {
      nspecial[i][0] = c1;
@@ -1229,7 +1204,8 @@ void Molecule::shakeflag_read(char *line)
  int tmp;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    sscanf(line,"%d %d",&tmp,&shake_flag[i]);
    if (2 != sscanf(line,"%d %d",&tmp,&shake_flag[i]))
      error->all(FLERR,"Invalid Shake Flags section in molecule file");
  }

  for (int i = 0; i < natoms; i++)
@@ -1243,23 +1219,32 @@ void Molecule::shakeflag_read(char *line)

void Molecule::shakeatom_read(char *line)
{
  int tmp;
  int tmp, nmatch, nwant;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (shake_flag[i] == 1)
      sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
             &tmp,&shake_atom[i][0],&shake_atom[i][1],&shake_atom[i][2]);
    else if (shake_flag[i] == 2)
      sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT,
    if (shake_flag[i] == 1) {
      nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT
                      " " TAGINT_FORMAT,&tmp,&shake_atom[i][0],
                      &shake_atom[i][1],&shake_atom[i][2]);
      nwant = 4;
    } else if (shake_flag[i] == 2) {
      nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT,
                      &tmp,&shake_atom[i][0],&shake_atom[i][1]);
    else if (shake_flag[i] == 3)
      sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT,
             &tmp,&shake_atom[i][0],&shake_atom[i][1],&shake_atom[i][2]);
    else if (shake_flag[i] == 4)
      sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " "
      nwant = 3;
    } else if (shake_flag[i] == 3) {
      nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT
                      " " TAGINT_FORMAT,&tmp,&shake_atom[i][0],
                      &shake_atom[i][1],&shake_atom[i][2]);
      nwant = 4;
    } else if (shake_flag[i] == 4) {
      nmatch = sscanf(line,"%d " TAGINT_FORMAT " " TAGINT_FORMAT " "
                      TAGINT_FORMAT " " TAGINT_FORMAT,
                      &tmp,&shake_atom[i][0],&shake_atom[i][1],
                      &shake_atom[i][2],&shake_atom[i][3]);
      nwant = 5;
    }
    if (nmatch != nwant)
      error->all(FLERR,"Invalid shake atom in molecule file");
  }

  for (int i = 0; i < natoms; i++) {
@@ -1277,19 +1262,27 @@ void Molecule::shakeatom_read(char *line)

void Molecule::shaketype_read(char *line)
{
  int tmp;
  int tmp,nmatch,nwant;
  for (int i = 0; i < natoms; i++) {
    readline(line);
    if (shake_flag[i] == 1)
      sscanf(line,"%d %d %d %d",&tmp,
             &shake_type[i][0],&shake_type[i][1],&shake_type[i][2]);
    else if (shake_flag[i] == 2)
      sscanf(line,"%d %d",&tmp,&shake_type[i][0]);
    else if (shake_flag[i] == 3)
      sscanf(line,"%d %d %d",&tmp,&shake_type[i][0],&shake_type[i][1]);
    else if (shake_flag[i] == 4)
      sscanf(line,"%d %d %d %d",&tmp,
             &shake_type[i][0],&shake_type[i][1],&shake_type[i][2]);
    if (shake_flag[i] == 1) {
      nmatch = sscanf(line,"%d %d %d %d",&tmp,&shake_type[i][0],
                      &shake_type[i][1],&shake_type[i][2]);
      nwant = 4;
    } else if (shake_flag[i] == 2) {
      nmatch = sscanf(line,"%d %d",&tmp,&shake_type[i][0]);
      nwant = 2;
    } else if (shake_flag[i] == 3) {
      nmatch = sscanf(line,"%d %d %d",&tmp,&shake_type[i][0],
                      &shake_type[i][1]);
      nwant = 3;
    } else if (shake_flag[i] == 4) {
      nmatch = sscanf(line,"%d %d %d %d",&tmp,&shake_type[i][0],
                      &shake_type[i][1],&shake_type[i][2]);
      nwant = 4;
    }
    if (nmatch != nwant)
      error->all(FLERR,"Invalid shake type data in molecule file");
  }

  for (int i = 0; i < natoms; i++) {