Skip to content

Commit d110046

Browse files
committed
Upd: validate the cron ;)
Rem: dependancy, didn't really work properly.
1 parent 3c0d113 commit d110046

File tree

2 files changed

+84
-39
lines changed

2 files changed

+84
-39
lines changed

composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
}
2424
],
2525
"require": {
26-
"php": ">=7.0",
27-
"hollodotme/crontab-validator": "^1.0"
26+
"php": ">=7.0"
2827
},
2928
"autoload": {
3029
"psr-4": {

src/CronLint.php

Lines changed: 83 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
use PHPCensor\Plugin;
1010
use PHPCensor\ZeroConfigPluginInterface;
1111

12-
use hollodotme\CrontabValidator\CrontabValidator;
13-
1412
/**
1513
* Crontab Linter.
1614
*
@@ -49,8 +47,6 @@ public function __construct(Builder $builder, Build $build, array $options = [])
4947
if (isset($options['files']) && is_array($options['files'])) {
5048
$this->files = $options['files'];
5149
}
52-
53-
$this->validator = new CrontabValidator();
5450
}
5551

5652
/**
@@ -69,30 +65,46 @@ public function execute()
6965
// $this->builder->logExecOutput(false);
7066
//
7167

72-
$this->validator = $validator = new CrontabValidator();
73-
7468
if (empty($this->files)) {
7569
return true;
7670
}
7771

72+
$success = true;
73+
7874
foreach ($this->files as $fileName) {
7975
$cronFile = sprintf('%s%s', $this->buildDir, $fileName);
80-
printf("%s\n", $cronFile);
81-
8276
if (!$this->validateFile($cronFile)) {
77+
$this->build->reportError(
78+
$this->builder,
79+
self::pluginName(),
80+
sprintf('Missing Cron File: %s', $fileName),
81+
BuildError::SEVERITY_NORMAL,
82+
$fileName
83+
);
8384
continue;
8485
}
8586

86-
$cronTab = file_get_contents($cronFile);
87+
$lineNo = 1;
88+
$cronTab = file_get_contents($cronFile);
8789
$cronLines = explode("\n", $cronTab);
8890
foreach ($cronLines as $line) {
89-
if (!$this->validateLine($line)) {
90-
continue;
91+
$errors = $this->validateLine($line);
92+
foreach ($errors as $err) {
93+
$this->build->reportError(
94+
$this->builder,
95+
self::pluginName(),
96+
$err,
97+
BuildError::SEVERITY_HIGH,
98+
$fileName,
99+
$lineNo
100+
);
101+
$success = false;
91102
}
103+
++$lineNo;
92104
}
93105
}
94106

95-
return true;
107+
return $success;
96108
}
97109

98110
// ------------------------------------------------------------------------
@@ -106,40 +118,74 @@ public function execute()
106118
*/
107119
protected function validateFile(string $file) : bool
108120
{
109-
if (!file_exists($file)) {
110-
$this->build->reportError(
111-
$this->builder,
112-
self::pluginName(),
113-
'Missing Cron File',
114-
BuildError::SEVERITY_NORMAL,
115-
$fileName
116-
);
117-
118-
return false;
119-
}
120-
121-
return true;
121+
return file_exists($file);
122122
}
123123

124124
/**
125125
* Validate Cron Line.
126126
*
127127
* @param string $line
128-
* @return bool
128+
* @return array
129129
*/
130-
protected function validateLine(string $line) : bool
130+
protected function validateLine(string $line) : array
131131
{
132-
if (!$this->validator->isIntervalValid($line)) {
133-
$this->build->reportError(
134-
$this->builder,
135-
self::pluginName(),
136-
sprintf('Invalid expression - %s', $line),
137-
BuildError::SEVERITY_HIGH,
138-
$fileName
139-
);
140-
return false;
132+
$errors = [];
133+
134+
// Skip comment lines or empty lines
135+
if (empty($line) || substr($line, 0, 1) == '#') {
136+
echo "empty/comment line\n";
137+
return $errors;
138+
}
139+
140+
$line = str_replace("\t", " ", $line);
141+
$args = array_values(
142+
array_filter(
143+
explode(" ", $line),
144+
function ($v) {
145+
return (bool) strlen($v);
146+
}
147+
)
148+
);
149+
$cmd = implode(' ', array_slice($args, 5));
150+
list($mins, $hours, $dayofmonth, $month, $dayofweek) = array_slice($args, 0, 5);
151+
152+
$regEx = [
153+
'minhour' => '/^([\*|\d]+)$|^([\*]\/\d+)$|^([\d+]\/\d+?(\-\d+))$|^(\d+-\d+\/[\d]+)$/i',
154+
'daymonth' => '/^(\d|\*)$/i',
155+
'month' => '/^(\d|\*)$/i',
156+
'dayweek' => '/^(\*|\d|[a-z]{3})$/i',
157+
'cmdoverflow' => '/^(\d|\*)$/i'
158+
];
159+
160+
if (!preg_match($regEx['minhour'], $mins)) {
161+
$errors[] = sprintf("Minutes invalid value: %s", $mins);
162+
}
163+
if (!preg_match($regEx['minhour'], $hours)) {
164+
$errors[] = sprintf("Hours invalid value: %s", $hours);
165+
}
166+
167+
$offset = 0;
168+
$dayofmonth = explode(',', $dayofmonth);
169+
foreach ($dayofmonth as $dom) {
170+
if (!preg_match($regEx['daymonth'], $dom)) {
171+
$errors[] = sprintf("Day of month[%d] invalid value: %s", $offset, $dom);
172+
}
173+
++$offset;
174+
}
175+
176+
$offset = 0;
177+
$dayofweek = explode(',', $dayofweek);
178+
foreach ($dayofweek as $dow) {
179+
if (!preg_match($regEx['dayweek'], $dow)) {
180+
$errors[] = sprintf("Day of week[%d] invalid value: %s", $offset, $dow);
181+
}
182+
++$offset;
183+
}
184+
185+
if (preg_match($regEx['cmdoverflow'], substr($cmd, 0, 1) == '*')) {
186+
$errors[] = sprintf("Cmd starts with invalid character: %s", $cmd);
141187
}
142188

143-
return true;
189+
return $errors;
144190
}
145191
}

0 commit comments

Comments
 (0)