Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Commit

Permalink
Add ablity to opt-out of iframe escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
calebporzio committed Mar 6, 2019
1 parent e3f5a61 commit a5f7cd2
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 7 deletions.
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,36 @@ GitDown::parseAndCache($markdown, function ($parse) {
});
```

## Allowing Iframes
By default, GitHub sanitizes HTML tags it deems "unsafe" like `<iframe>`s. However, it's common to embed video or audio into your markdown with `<iframe>`s.

GitDown can intelligently preserve your iframes by setting the `allowIframes` config option in `config/gitdown.php` to `true`.

```php
"allowIframes" => true,
```

## Non-Laravel Usage
You can set a GitHub Personal Access Token by passing it into the `GitDown`'s constructor.
`new GitDown\GitDown($token)`

```php
(new GitDown\GitDown($token))->parse($markdown);
// You can pass config options into the constructur:
$gitDown = new GitDown\GitDown(
$token = 'foo',
$context = 'your/repo',
$allowIframes = false
);

$gitDown->parse($markdown);

// Pass in your own custom caching strategy.
(new GitDown\GitDown($token))->parseAndCache($markdown, function ($parse) {
$gitDown->parseAndCache($markdown, function ($parse) {
return Cache::rememberForever(sha1($markdown), function () use ($parse) {
return $parse();
});
});

```

## Markdown/Syntax CSS
Expand Down
55 changes: 51 additions & 4 deletions src/GitDown.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,34 @@ class GitDown
{
protected $token;
protected $context;
protected $allowIframes;

public function __construct($token = null, $context = null)
public function __construct($token = null, $context = null, $allowIframes = false)
{
$this->token = $token;
$this->context = $context;
$this->allowIframes = $allowIframes;
}

public function setToken($token)
{
$this->token = $token;

return $this;
}

public function setContext($token)
public function setContext($context)
{
$this->context = $context;

return $this;
}

public function withIframes()
{
$this->allowIframes = true;

return $this;
}

public function parse($content)
Expand All @@ -31,14 +44,48 @@ public function parse($content)
'User-Agent' => 'GitDown Plugin',
] + ($this->token ? ['Authorization' => 'token '.$this->token] : []))
->post('https://api.github.com/markdown', [
'text' => $content,
'text' => $this->encryptIframeTags($content),
] + ($this->context ? ['mode' => 'gfm', 'context' => $this->context] : []));

if (! $response->isOk()) {
throw new \Exception('GitHub API Error: ' . $response->body());
}

return (string) $response;
return $this->decryptIframeTags((string) $response);
}

public function encryptIframeTags($input)
{
if (! $this->allowIframes) {
return $input;
}

if (! preg_match_all('/<iframe[^>]*?(?:\/>|>[^<]*?<\/iframe>)/', $input, $matches)) {
return $input;
};

foreach ($matches[0] as $match) {
$input = str_replace($match, '\[iframe\]'. base64_encode($match).'\[endiframe\]', $input);
}

return $input;
}

public function decryptIframeTags($input)
{
if (! $this->allowIframes) {
return $input;
}

if (! preg_match_all('/\[iframe\].*\[endiframe\]/', $input, $matches)) {
return $input;
};

foreach ($matches[0] as $match) {
$input = str_replace($match, base64_decode(ltrim(rtrim($match, '[endiframe]'), '[iframe]')), $input);
}

return $input;
}

public function parseAndCache($content, $minutes = null)
Expand Down
6 changes: 5 additions & 1 deletion src/GitDownServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ class GitDownServiceProvider extends ServiceProvider
public function register()
{
app()->singleton('gitdown', function () {
return new GitDown(config('gitdown.token'));
return new GitDown(
config('gitdown.token'),
config('gitdown.context'),
config('gitdown.allowIframes')
);
});
}

Expand Down
13 changes: 13 additions & 0 deletions src/config-stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,17 @@

'context' => null,

/*
|--------------------------------------------------------------------------
| Allow Iframes
|--------------------------------------------------------------------------
|
| By default, GitHub escapes any HTML tags it deems "unsafe" while parsing.
| For example, passing in a string like "<iframe></iframe>" will output
| "&lt;iframe&gt;&lt;/iframe&gt;". This config will work-around this.
|
*/

'allowIframes' => false,

];
8 changes: 8 additions & 0 deletions tests/GitDownTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,12 @@ protected function cacheStrategy(&$callCount)
}
};
}

/** @test */
public function parsed_html_preserves_iframes()
{
$parsed = (new GitDown(null, null, $allowIframes = true))->parse('<iframe></iframe>');

$this->assertEquals('<p><iframe></iframe></p>', trim($parsed));
}
}

0 comments on commit a5f7cd2

Please sign in to comment.