Skip to content

Commit

Permalink
Escape all string values in broken json from php-fpm status
Browse files Browse the repository at this point in the history
Should fix hipages#258 and hipages#291
  • Loading branch information
jvrsantacruz committed Apr 3, 2023
1 parent 9acae7b commit 2c759a2
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
25 changes: 13 additions & 12 deletions phpfpm/phpfpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,22 @@ func (p *Pool) error(err error) error {
return err
}

// JSONResponseFixer resolves encoding issues with PHP-FPMs JSON response
func JSONResponseFixer(content []byte) []byte {
c := string(content)
re := regexp.MustCompile(`(,"request uri":)"(.*?)"(,"content length":)`)
matches := re.FindAllStringSubmatch(c, -1)

for _, match := range matches {
requestURI, _ := json.Marshal(match[2])
reValue := regexp.MustCompile(`^"(.*)"(,)?$`)
reKey := regexp.MustCompile(`"[^"]+":`)

sold := match[0]
snew := match[1] + string(requestURI) + match[3]

c = strings.ReplaceAll(c, sold, snew)
c := string(content)
values := reKey.Split(c, -1)
for _, value := range values {
matches := reValue.FindAllSubmatch([]byte(value), 1)
if len(matches) == 1 {
escaped, _ := json.Marshal(string(matches[0][1]))
if(len(matches[0]) > 2) {
escaped = append(escaped, matches[0][2]...)
}
c = strings.ReplaceAll(c, string(matches[0][0]), string(escaped))
}
}

return []byte(c)
}

Expand Down
4 changes: 3 additions & 1 deletion phpfpm/phpfpm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,17 @@ func TestInvalidCharacterIssue24(t *testing.T) {

func TestJsonResponseFixer(t *testing.T) {
pool := Pool{}
content := []byte(`{"pool":"www","process manager":"dynamic","start time":1528367006,"start since":15073840,"accepted conn":1577112,"listen queue":0,"max listen queue":0,"listen queue len":0,"idle processes":16,"active processes":1,"total processes":17,"max active processes":15,"max children reached":0,"slow requests":0, "processes":[{"pid":15873,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"-","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432},{"pid":123,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"123/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"-","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432}]}`)
content := []byte(`{"pool":"www","process manager":"dynamic","start time":1528367006,"start since":15073840,"accepted conn":1577112,"listen queue":0,"max listen queue":0,"listen queue len":0,"idle processes":16,"active processes":1,"total processes":17,"max active processes":15,"max children reached":0,"slow requests":0, "processes":[{"pid":15873,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"my\windows\program","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432},{"pid":123,"state":"Idle","start time":1543354120,"start since":86726,"requests":853,"request duration":5721,"request method":"GET","request uri":"123/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00","content length":0,"user":"eol\n","script":"/www/forum.example.com/vbseo.php","last request cpu":349.59,"last request memory":786432}]}`)

content = JSONResponseFixer(content)

err := json.Unmarshal(content, &pool)

assert.Nil(t, err, "successfully unmarshal on invalid 'request uri'")
assert.Equal(t, pool.Processes[0].RequestURI, `/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00`, "request uri couldn't be deserialized")
assert.Equal(t, pool.Processes[0].User, `my\windows\program`, "user couldn't be deserialized")
assert.Equal(t, pool.Processes[1].RequestURI, `123/vbseo.php?ALTERNATE_TEMPLATES=|%20echo%20"Content-Type:%20text%2Fhtml"%3Becho%20""%20%3B%20id%00`, "request uri couldn't be deserialized")
assert.Equal(t, pool.Processes[1].User, `eol\n`, "user couldn't be deserialized")
}

func TestParseURL(t *testing.T) {
Expand Down

0 comments on commit 2c759a2

Please sign in to comment.