This issue is a result of a Codex global code scan of deepmodeling/fpop at commit b05b337590c31a5237b2dcbd9c0833b841c08cd4.
Relevant code:
|
def get_pporbdpks_from_stru(stru: str= "STRU"): |
|
"read the label, pp, orb, cell, coord, deepks-descriptor" |
|
ABACUS_STRU_KEY_WORD = [ |
|
"ATOMIC_SPECIES", |
|
"NUMERICAL_ORBITAL", |
|
"LATTICE_CONSTANT", |
|
"LATTICE_VECTORS", |
|
"ATOMIC_POSITIONS", |
|
"NUMERICAL_DESCRIPTOR", |
|
] |
|
if not os.path.isfile(stru): |
|
return {} |
|
with open(stru) as f1: lines = f1.readlines() |
|
def get_block(keyname): |
|
block = [] |
|
for i,line in enumerate(lines): |
|
if line.strip() == "": continue |
|
elif line.split('#')[0].strip() == keyname: |
|
for ij in range(i+1,len(lines)): |
|
if lines[ij].strip() == "": continue |
|
elif lines[ij].strip() in ABACUS_STRU_KEY_WORD: |
|
return block |
|
else: |
|
block.append(lines[ij]) |
|
return block |
|
return None |
|
|
|
atomic_species = get_block("ATOMIC_SPECIES") |
|
numerical_orbital = get_block("NUMERICAL_ORBITAL") |
|
dpks = get_block("NUMERICAL_DESCRIPTOR") |
|
dpks = None if dpks == None else dpks[0].strip() |
|
|
|
#read species |
|
pp = [] |
|
labels = [] |
|
mass = [] |
|
if atomic_species: |
|
for line in atomic_species: |
|
sline = line.split() |
|
labels.append(sline[0]) |
|
pp.append(sline[2]) |
|
mass.append(float(sline[1])) |
|
|
|
#read orbital |
|
if numerical_orbital == None: |
|
orb = None |
|
else: |
|
orb = [] |
|
for line in numerical_orbital: |
|
orb.append(line.split()[0]) |
|
|
|
return { |
|
"labels": labels, |
|
"mass": mass, |
|
"pp":pp, |
|
"orb":orb, |
|
"dpks":dpks,} |
|
class RunAbacus(RunFp): |
|
def input_files(self,task_path) -> List[str]: |
|
r'''The mandatory input files to run an abacus task. |
|
Returns |
|
------- |
|
files: List[str] |
|
A list of madatory input files names. |
|
''' |
|
|
|
cwd = os.getcwd() |
|
os.chdir(task_path) |
|
|
|
files = ["INPUT","STRU"] |
|
if os.path.isfile("KPT"): |
|
files.append("KPT") |
|
|
|
files_tmp = [] |
|
#read STRU |
|
stru_data = get_pporbdpks_from_stru("STRU") |
|
if stru_data != None: |
|
orb_files = stru_data["orb"] |
|
pp_files = stru_data["pp"] |
|
dpks_descriptor = stru_data["dpks"] |
|
|
|
files_tmp += pp_files |
|
if orb_files: files_tmp += orb_files |
|
if dpks_descriptor: files_tmp += [dpks_descriptor] |
|
|
|
#read INPUT |
|
input = AbacusInputs.read_inputf("INPUT") |
|
if "deepks_model" in input: files_tmp += [input["deepks_model"]] |
|
|
|
for ii in files_tmp: |
|
if os.path.isfile(ii): |
|
files.append(ii) |
|
else: |
|
print("ERROR: file %s is not found" % ii) |
|
|
|
os.chdir(cwd) |
|
|
|
return files |
Problem:
RunAbacus.input_files() changes the process working directory with os.chdir(task_path) and restores it only on the successful path. If STRU parsing raises, the caller is left in the task directory.
There are at least two easy ways to trigger this:
- If
STRU is missing, get_pporbdpks_from_stru("STRU") returns {}. input_files() checks if stru_data != None, then indexes stru_data["orb"] and raises KeyError.
- If a STRU section header has an inline comment, such as
NUMERICAL_ORBITAL # comment, get_block() does not strip comments when detecting the next section header. The commented header is treated as an ATOMIC_SPECIES data line and parsing can fail with ValueError: could not convert string to float: '#'.
Minimal reproduction for the second case:
ATOMIC_SPECIES
H 1 H.upf
NUMERICAL_ORBITAL # comment
H.orb
LATTICE_CONSTANT
1
Expected behavior:
RunAbacus.input_files() should restore cwd in a finally block, and STRU parsing failures should be reported as clear missing/invalid input errors instead of leaking process state.
This issue is a result of a Codex global code scan of
deepmodeling/fpopat commitb05b337590c31a5237b2dcbd9c0833b841c08cd4.Relevant code:
fpop/fpop/abacus.py
Lines 249 to 305 in b05b337
fpop/fpop/abacus.py
Lines 556 to 596 in b05b337
Problem:
RunAbacus.input_files()changes the process working directory withos.chdir(task_path)and restores it only on the successful path. If STRU parsing raises, the caller is left in the task directory.There are at least two easy ways to trigger this:
STRUis missing,get_pporbdpks_from_stru("STRU")returns{}.input_files()checksif stru_data != None, then indexesstru_data["orb"]and raisesKeyError.NUMERICAL_ORBITAL # comment,get_block()does not strip comments when detecting the next section header. The commented header is treated as anATOMIC_SPECIESdata line and parsing can fail withValueError: could not convert string to float: '#'.Minimal reproduction for the second case:
Expected behavior:
RunAbacus.input_files()should restore cwd in afinallyblock, and STRU parsing failures should be reported as clear missing/invalid input errors instead of leaking process state.