Skip to content

Conversation

@justinsteven
Copy link
Contributor

I'm not sure why we're reading the data file as we are, preventing the use of -bulk for stdin. This diff works in my limited testing for regular files in non-bulk and bulk mode, as well as stdin in non-bulk and bulk mode.

Being able to send stdin as bulk improves the speed of sending notifications and can result in less notification clutter.

Using -bulk with stdin means that, unless we do chunked reads, notify needs to wait for EOF. But if a user is using -bulk with stdin then hopefully they expect this behaviour.

Demo:

% time ./notify -silent -i /etc/passwd >/dev/null
./notify -silent -i /etc/passwd > /dev/null  0.06s user 0.07s system 1% cpu 9.649 total

% time ./notify -silent -i /etc/passwd -bulk >/dev/null
./notify -silent -i /etc/passwd -bulk > /dev/null  0.07s user 0.03s system 28% cpu 0.376 total

% grep discover /usr/share/dict/words | wc -l
17

% grep discover /usr/share/dict/words | time ./notify -silent >/dev/null
./notify -silent > /dev/null  0.06s user 0.03s system 1% cpu 4.648 total

% grep discover /usr/share/dict/words | time ./notify -silent -bulk >/dev/null
./notify -silent -bulk > /dev/null  0.05s user 0.04s system 26% cpu 0.344 total

@ehsandeep ehsandeep requested review from Mzack9999 and parrasajad May 18, 2022 17:59
@ehsandeep ehsandeep changed the base branch from master to dev May 18, 2022 18:00
@ehsandeep ehsandeep added the Status: Review Needed The issue has a PR attached to it which needs to be reviewed label May 18, 2022
Copy link
Member

@Mzack9999 Mzack9999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only potential problem I can see (and why the bulk was not allowed with stdin) is massive stdin input that, when used with -bulk will read all the content in memory. Probably making it clear in the docs should suffice.

@justinsteven
Copy link
Contributor Author

@Mzack9999 That's fair. I'm seeing what can be done to use bufio.Scanner with a custom SplitFunc, essentially replacing SplitText. Seems promising. Just working out some kinks.

Reduces memory usage when input is big

Also includes the fix for projectdiscovery#134 (makes testing easier)
@justinsteven
Copy link
Contributor Author

Note that I've incorporated #135 into this PR to make testing easier. It's easily enough backed out if that PR isn't approved. I'm also abusing #136 which is a quirk I'm now warming to for testing purposes.

I've implemented chunked reading for -bulk. I'd appreciate a careful review and any relevant polish, I'm still getting my feet under me with Go.

Large inputs no longer cause excessive memory usage in my limited testing (it's hard to trick notify into processing lots of data quickly lol)

As of the previous commit, notifying an invalid webhook of 500MB of data took 4GB of memory (!). I'm using an invalid webhook for speed - notify will still process the data but will quickly fail to do anything useful with it.

% base64 /dev/urandom -w10000 | head -c 500M > 500M.txt

% ls -lah 500M.txt
-rw-r--r-- 1 justin justin 500M May 20 17:33 500M.txt

% cat provider-invalid-webhook.yaml
custom:
  - id: "webhook"
    custom_webook_url: "http://127.0.0.1:1/"
    custom_method: GET
    custom_format: '{{data}}'
    custom_headers: {}

% /usr/bin/env time -f 'Took %E, used %M KB memory' ./notify -bulk -provider-config provider-invalid-webhook.yaml -i 500M.txt 2>&1 | tail -n1
Took 0:33.48, used 4179540 KB memory

The new approach uses 22MB of memory:

% /usr/bin/env time -f 'Took %E, used %M KB memory' ./notify -bulk -provider-config provider-invalid-webhook.yaml -i 500M.txt 2>&1 | tail -n1
Took 0:31.58, used 22800 KB memory

Notifying seems to still be correctly implemented for normal inputs:

% cmp <(./notify -silent -bulk -i /etc/passwd) <(cat /etc/passwd) && echo matches
matches

% cmp <(./notify -silent -bulk -i /dev/null) <(cat /dev/null) && echo matches
matches

% cmp <(python -c'print("A"*2048)' | ./notify -silent -bulk) <(python -c'print("A"*2048)') && echo matches
matches

Where testing gets trickier is with the chunking.

generate.py will generate patterns of increasing length, and will optionally chunk long lines at a given length to simulate notify's -char-limit

% cat generate.py
#!/usr/bin/env python3
import argparse
from string import ascii_lowercase
from itertools import cycle, islice

parser = argparse.ArgumentParser()
parser.add_argument("-c", "--chunk", type=int,
                    help="Chunk each line at a certain interval")
parser.add_argument("min", type=int)
parser.add_argument("max", type=int)
parser.add_argument("step", type=int, default=1, nargs="?")

args = parser.parse_args()

for i in range(args.min, args.max, args.step):
  line = "".join(islice(cycle(ascii_lowercase), i))
  if args.chunk is not None:
    line = "\n".join(line[i:i+args.chunk] for i in range(0, len(line), args.chunk))
  print(line)
% ./generate.py 0 100 10

abcdefghij
abcdefghijklmnopqrst
abcdefghijklmnopqrstuvwxyzabcd
abcdefghijklmnopqrstuvwxyzabcdefghijklmn
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl

% ./generate.py 0 100 10 -c 33

abcdefghij
abcdefghijklmnopqrst
abcdefghijklmnopqrstuvwxyzabcd
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmn
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmnopqrstuvwx
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmnopqrstuvwxyzabcdefgh
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmnopqrstuvwxyzabcdefghijklmn
opqr
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmnopqrstuvwxyzabcdefghijklmn
opqrstuvwxyzab
abcdefghijklmnopqrstuvwxyzabcdefg
hijklmnopqrstuvwxyzabcdefghijklmn
opqrstuvwxyzabcdefghijkl

The new chunking approach seems to faithfully notify data of this nature:

% cmp <(./generate.py 3000 5000 100 | ./notify -silent -bulk -char-limit 4000) <(./generate.py 3000 5000 100 -c4000) && echo matches
matches

@justinsteven
Copy link
Contributor Author

Given this approach, internal/runner/util.go's SplitText() is now dead code as far as notify is concerned. It's the only thing in util.go. If this approach is viable, can that file now be removed? Or could other projects be importing it?

Copy link
Member

@ehsandeep ehsandeep left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Slack rate limit
  • index out of range crash
[ERR] failed to send slack notification for id: slack : failed to send slack notification: webhook response: too_many_attachments
panic: runtime error: index out of range [3990] with length 3990

goroutine 1 [running]:
github.com/containrrr/shoutrrr/pkg/util.PartitionMessage({0x14000497000, 0xf96}, {0x7d0, 0x1770, 0xa}, 0x64)
	/Users/geekboy/go/pkg/mod/github.com/containrrr/[email protected]/pkg/util/partition_message.go:33 +0x2ec
github.com/containrrr/shoutrrr/pkg/services/discord.CreateItemsFromPlain({0x14000497000, 0xf96}, 0x0)
	/Users/geekboy/go/pkg/mod/github.com/containrrr/[email protected]/pkg/services/discord/discord.go:84 +0xc0
github.com/containrrr/shoutrrr/pkg/services/discord.(*Service).Send(0x1400013b440, {0x14000497000, 0xf96}, 0x14000138308)
	/Users/geekboy/go/pkg/mod/github.com/containrrr/[email protected]/pkg/services/discord/discord.go:42 +0x164
github.com/containrrr/shoutrrr.Send({0x1400029e3f0, 0x6f}, {0x14000497000, 0xf96})
	/Users/geekboy/go/pkg/mod/github.com/containrrr/[email protected]/shoutrrr.go:23 +0xcc
github.com/projectdiscovery/notify/pkg/providers/discord.(*Provider).Send(0x14000128a98, {0x14000505000, 0xf96}, {0x140002a9bb0, 0x8})
	/Users/geekboy/Github/notify/pkg/providers/discord/discord.go:54 +0x32c
github.com/projectdiscovery/notify/pkg/providers.(*Client).Send(0x140002c3380, {0x1400037f000, 0xf96})
	/Users/geekboy/Github/notify/pkg/providers/providers.go:113 +0xd4
github.com/projectdiscovery/notify/internal/runner.(*Runner).sendMessage(0x140002212d0, {0x1400037f000, 0xf96})
	/Users/geekboy/Github/notify/internal/runner/runner.go:169 +0xa4
github.com/projectdiscovery/notify/internal/runner.(*Runner).Run(0x140002212d0)
	/Users/geekboy/Github/notify/internal/runner/runner.go:108 +0x614
main.main()
	/Users/geekboy/Github/notify/cmd/notify/notify.go:42 +0x1a8

@justinsteven
Copy link
Contributor Author

@ehsandeep I can more of less repro both of those problems on master. I think they're bugs in shoutrrr.

I'll consider what we can do in terms of being less aggressive with our -bulk (e.g. limiting the number of chars to no more than charLimit AND limiting our lines to no more than 100?) and/or cranking down our default -char-limit to stay away from the problems. I'll also consider filing bugs at shoutrrr.

@justinsteven
Copy link
Contributor Author

Repro for the attachments error on this PR:

% yes | head -n 100 | ./notify -bulk >/dev/null

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.2-dev
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml

% yes | head -n 101 | ./notify -bulk >/dev/null

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.2-dev
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
[ERR] failed to send slack notification for id: slack : failed to send slack notification: webhook response: too_many_attachments

Note that the error triggers on >100 lines in a single message. It's not affected by the length of the lines.

Reproing a similar-enough issue on master:

% tmpfile=$(mktemp)

% yes | head -n 100 > $tmpfile

% ./notify -i $tmpfile -bulk 2>&1 | grep -Pv '^y$'

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.1
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
[ERR] failed to send slack notification for id: slack : failed to send slack notification: response status code 413 Request Entity Too Large

Reproing the index out of range crash on master (note that the stack trace shows it being a problem in shoutrrr)

% yes | head -n999 > $tmpfile

% ./notify -pc provider-discord.yaml -bulk -i $tmpfile 2>&1 | grep -Pv '^y$'

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.1
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.

% yes | head -n1000 > $tmpfile

% ./notify -pc provider-discord.yaml -bulk -i $tmpfile 2>&1 | grep -Pv '^y$'

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.1
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
panic: runtime error: index out of range [2000] with length 2000

goroutine 1 [running]:
github.com/containrrr/shoutrrr/pkg/util.PartitionMessage({0xc0001ea000, 0x199}, {0x30, 0xc00013f938, 0x40e774}, 0x64)
        /home/justin/go/pkg/mod/github.com/containrrr/[email protected]/pkg/util/partition_message.go:33 +0x3d1
github.com/containrrr/shoutrrr/pkg/services/discord.CreateItemsFromPlain({0xc0001ea000, 0x7f54b1b1d108}, 0x30)
        /home/justin/go/pkg/mod/github.com/containrrr/[email protected]/pkg/services/discord/discord.go:84 +0x65
github.com/containrrr/shoutrrr/pkg/services/discord.(*Service).Send(0xc0000210e0, {0xc0001ea000, 0xc00013f9a8}, 0x40c207)
        /home/justin/go/pkg/mod/github.com/containrrr/[email protected]/pkg/services/discord/discord.go:42 +0x145
github.com/containrrr/shoutrrr.Send({0xc000076310, 0x1d}, {0xc0001ea000, 0x7d0})
        /home/justin/go/pkg/mod/github.com/containrrr/[email protected]/shoutrrr.go:22 +0x9f
github.com/projectdiscovery/notify/pkg/providers/discord.(*Provider).Send(0xc00011b4a0, {0xc0001e1800, 0x7d0}, {0xc00002edc8, 0x8})
        /home/justin/opt/notify/pkg/providers/discord/discord.go:54 +0x2d9
github.com/projectdiscovery/notify/pkg/providers.(*Client).Send(0xc000175350, {0xc0001dd000, 0xc0001dc800})
        /home/justin/opt/notify/pkg/providers/providers.go:113 +0xdb
github.com/projectdiscovery/notify/internal/runner.(*Runner).sendMessage(0xc0001da110, {0xc0001dd000, 0xfa0})
        /home/justin/opt/notify/internal/runner/runner.go:146 +0xa5
github.com/projectdiscovery/notify/internal/runner.(*Runner).Run(0xc0001da110)
        /home/justin/opt/notify/internal/runner/runner.go:125 +0xad0
main.main()
        /home/justin/opt/notify/cmd/notify/notify.go:42 +0x1b1

@justinsteven
Copy link
Contributor Author

Slack issue filed at containrrr/shoutrrr#238

Discord issue filed at containrrr/shoutrrr#240 but note that I could only repro the Discord issue with messages of 2000, 4000 or 6000 chars. The panic seen by @ehsandeep seems to be on a message of 3990 chars, which I can't repro. It might or might not be related to the issue I filed at shoutrrr.

TODO: Do what we can to avoid the shoutrrr crashes until such time as they're fixed

Simplified looping. Also, we no longer truncate mid-line unless it's the first
line of a chunk (in such a case we have no option but to truncate). A truncated
line will be followed by an ellipsis. Otherwise we're splitting chunks at the
last possible newline without exceeding charLimit for that chunk.
@justinsteven
Copy link
Contributor Author

New strategy for the splitter.

We no longer truncate mid-line unless it's the first line of a chunk (in such a case we have no option but to truncate). A truncated line will be followed by an ellipsis. Otherwise we're splitting chunks at the last possible newline without exceeding charLimit for that chunk.

Demo:

% python3 -c 'import string; print(string.ascii_lowercase)' | ./notify -silent -bulk -char-limit 12
abcdefghi...
jklmnopqr...
stuvwxyz

% python3 -c 'print("A"*26 + "\nBBBB")' | ./notify -silent -bulk -char-limit 12
AAAAAAAAA...
AAAAAAAAA...
AAAAAAAA
BBBB

% python3 -c 'print("AAAA\n" + "B"*26)' | ./notify -silent -bulk -char-limit 12
AAAA
BBBBBBBBB...
BBBBBBBBB...
BBBBBBBB

@justinsteven
Copy link
Contributor Author

The previous tests I was doing also still pass, except for the generate.py ones (I'll consider if I need to create a testing strategy for the new split logic. The above demo might suffice)

#!/bin/bash

cd $(dirname "$(readlink -f "$0")")

heading() {
    echo "[+] $1"
}

provider_invalid_webhook=provider-invalid-webhook.yaml
provider_discord=provider-discord.yaml
provider_slack=provider-slack.yaml

heading /etc/passwd
cmp <(./notify -provider-config $provider_invalid_webhook -silent -bulk -i /etc/passwd) \
    <(cat /etc/passwd) && echo matches

heading /dev/null
cmp <(./notify -provider-config $provider_invalid_webhook -silent -bulk -i /dev/null) \
    <(cat /dev/null) && echo matches

heading AAAA
cmp <(python -c'print("A"*2048)' | ./notify -provider-config $provider_invalid_webhook -silent -bulk) \
    <(python -c'print("A"*2048)') && echo matches

#heading generate.py
#cmp <(./generate.py 0 8000 1 | ./notify -provider-config $provider_invalid_webhook -silent -bulk -char-limit 4000) \
#    <(./generate.py 0 8000 1 -c4000) && echo matches

heading 'slack attachment limit (trying 100 lines)'
yes | head -n100 | ./notify -provider-config $provider_slack -bulk 2>&1 >/dev/null| grep too_many_attachments
heading 'slack attachment limit (trying 101 lines)'
yes | head -n101 | ./notify -provider-config $provider_slack -bulk 2>&1 >/dev/null | grep too_many_attachments

heading 'discord characters being 2000, 4000 or 6000 (trying 1999 lines)'
python3 -c'print("A"*1999)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
heading 'discord characters being 2000, 4000 or 6000 (trying 2000 lines)'
python3 -c'print("A"*2000)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
heading 'discord characters being 2000, 4000 or 6000 (trying 2001 lines)'
python3 -c'print("A"*2001)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
% ./test.sh
[+] /etc/passwd
matches
[+] /dev/null
matches
[+] AAAA
matches
[+] slack attachment limit (trying 100 lines)
[+] slack attachment limit (trying 101 lines)
[ERR] failed to send slack notification for id: slack : failed to send slack notification: webhook response: too_many_attachments
[+] discord characters being 2000, 4000 or 6000 (trying 1999 lines)
[+] discord characters being 2000, 4000 or 6000 (trying 2000 lines)
panic: runtime error: index out of range [2000] with length 2000
[+] discord characters being 2000, 4000 or 6000 (trying 2001 lines)

The bugs in shoutrrr are still present. Note that shoutrrr has merged fixes for them already, but has not cut a release. We might be able to simply hold off for that release, or bump go.mod to point to a commit that includes the fixes.

Inclues fixes for:

* containrrr/shoutrrr#238
  * Sending more than ~99 lines to Slack fails with too_many_attachments
* containrrr/shoutrrr#240
  * Sending 2000, 4000 or 6000 characters to Discord panics
* containrrr/shoutrrr#244
  * Sending 1999, 3999 or 5999 characters to Discord panics
  * (Incomplete fix for the above)
@justinsteven
Copy link
Contributor Author

Bumped the shoutrrr module to an unreleased commit which includes fixes for the panics I could repro.

Note that I could not repro the crash on 3990 characters. Hopefully shoutrrr's fixes also address whatever the issue was.

This is now ready for review.

test.sh:

#!/bin/bash

cd $(dirname "$(readlink -f "$0")")

heading() {
    echo "[+] $1"
}

provider_invalid_webhook=provider-invalid-webhook.yaml
provider_discord=provider-discord.yaml
provider_slack=provider-slack.yaml

heading /etc/passwd
cmp <(./notify -provider-config $provider_invalid_webhook -silent -bulk -i /etc/passwd) \
    <(cat /etc/passwd) && echo matches

heading /dev/null
cmp <(./notify -provider-config $provider_invalid_webhook -silent -bulk -i /dev/null) \
    <(cat /dev/null) && echo matches

heading AAAA
cmp <(python -c'print("A"*2048)' | ./notify -provider-config $provider_invalid_webhook -silent -bulk) \
    <(python -c'print("A"*2048)') && echo matches

#heading generate.py
#cmp <(./generate.py 0 8000 1 | ./notify -provider-config $provider_invalid_webhook -silent -bulk -char-limit 4000) \
#    <(./generate.py 0 8000 1 -c4000) && echo matches

heading 'slack attachment limit (trying 100 lines)'
yes | head -n100 | ./notify -provider-config $provider_slack -bulk 2>&1 >/dev/null| grep too_many_attachments
heading 'slack attachment limit (trying 101 lines)'
yes | head -n101 | ./notify -provider-config $provider_slack -bulk 2>&1 >/dev/null | grep too_many_attachments

heading 'discord characters being 2000, 4000 or 6000 (trying 1999 lines)'
python3 -c'print("A"*1999)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
heading 'discord characters being 2000, 4000 or 6000 (trying 2000 lines)'
python3 -c'print("A"*2000)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
heading 'discord characters being 2000, 4000 or 6000 (trying 2001 lines)'
python3 -c'print("A"*2001)' | ./notify -provider-config $provider_discord -bulk 2>&1 >/dev/null | grep panic
% ./test.sh
[+] /etc/passwd
matches
[+] /dev/null
matches
[+] AAAA
matches
[+] slack attachment limit (trying 100 lines)
[+] slack attachment limit (trying 101 lines)
[+] discord characters being 2000, 4000 or 6000 (trying 1999 lines)
[+] discord characters being 2000, 4000 or 6000 (trying 2000 lines)
[+] discord characters being 2000, 4000 or 6000 (trying 2001 lines)
% ~/.local/bin/cyclic 8000 | ./notify -bulk -id discord

             __  _ ___
  ___  ___  / /_(_) _/_ __
 / _ \/ _ \/ __/ / _/ // /
/_//_/\___/\__/_/_/ \_, / v1.0.2-dev
                   /___/

                projectdiscovery.io

Use with caution. You are responsible for your actions
Developers assume no liability and are not responsible for any misuse or damage.
Using default provider config: /home/justin/.config/notify/provider-config.yaml
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaafkaaflaafmaafnaafoaafpaafqaafraafsaaftaafuaafvaafwaafxaafyaafzaagbaagcaagdaageaagfaaggaaghaagiaagjaagkaaglaagmaagnaagoaagpaagqaagraagsaagtaaguaagvaagwaagxaagyaagzaahbaahcaahdaaheaahfaahgaahhaahiaahjaahkaahlaahmaahnaahoaahpaahqaahraahsaahtaahuaahvaahwaahxaahyaahzaaibaaicaaidaaieaaifaaigaaihaaiiaaijaaikaailaaimaainaaioaaipaaiqaairaaisaaitaaiuaaivaaiwaaixaaiyaaizaajbaajcaajdaajeaajfaajgaajhaajiaajjaajkaajlaajmaajnaajoaajpaajqaajraajsaajtaajuaajvaajwaajxaajyaajzaakbaakcaakdaakeaakfaakgaakhaakiaakjaakkaaklaakmaaknaakoaakpaakqaakraaksaaktaakuaakvaakwaakxaakyaakzaalbaalcaaldaaleaalfaalgaalhaaliaaljaalkaallaalmaalnaaloaalpaalqaalraalsaaltaaluaalvaalwaalxaalyaalzaambaamcaamdaameaamfaamgaamhaamiaamjaamkaamlaammaamnaamoaampaamqaamraamsaamtaamuaamvaamwaamxaamyaamzaanbaancaandaaneaanfaangaanhaaniaanjaankaanlaanmaannaanoaanpaanqaanraansaantaanuaanvaanwaanxaanyaanzaaobaaocaaodaaoeaaofaaogaaohaaoiaaojaaokaaolaaomaaonaaooaaopaaoqaaoraaosaaotaaouaaovaaowaaoxaaoyaaozaapbaapcaapdaapeaapfaapgaaphaapiaapjaapkaaplaapmaapnaapoaappaapqaapraapsaaptaapuaapvaapwaapxaapyaapzaaqbaaqcaaqdaaqeaaqfaaqgaaqhaaqiaaqjaaqkaaqlaaqmaaqnaaqoaaqpaaqqaaqraaqsaaqtaaquaaqvaaqwaaqxaaqyaaqzaarbaarcaardaareaarfaargaarhaariaarjaarkaarlaarmaarnaaroaarpaarqaarraarsaartaaruaarvaarwaarxaaryaarzaasbaascaasdaaseaasfaasgaashaasiaasjaaskaaslaasmaasnaasoaaspaasqaasraassaastaasuaasvaaswaasxaasyaaszaatbaatcaatdaateaatfaatgaathaatiaatjaatkaatlaatmaatnaatoaatpaatqaatraatsaattaatuaatvaatwaatxaatyaatzaaubaaucaaudaaueaaufaaugaauhaauiaaujaaukaaulaaumaaunaauoaaupaauqaauraausaautaauuaauvaauwaauxaauyaauzaavbaavcaavdaaveaavfaavgaavhaaviaavjaavkaavlaavmaavnaavoaavpaavqaavraavsaavtaavuaavvaavwaavxaavyaavzaawbaawcaawdaaweaawfaawgaawhaawiaawjaawkaawlaawmaawnaawoaawpaawqaawraawsaawtaawuaawvaawwaawxaawyaawzaaxbaaxcaaxdaaxeaaxfaaxgaaxhaaxiaaxjaaxkaaxlaaxmaaxnaaxoaaxpaaxqaaxraaxsaaxtaaxuaaxvaaxwaaxxaaxyaaxzaaybaaycaaydaayeaayfaaygaayhaayiaayjaaykaaylaaymaaynaayoaaypaayqaayraaysaaytaayuaayvaaywaayxaayyaayzaazbaazcaazdaazeaazfaazgaazhaaziaazjaazkaazlaazmaaznaazoaazpaazqaazraazsaaztaazuaazvaazwaazxaazyaazzababacabadabaeabafabagabahabaiabajabakabalabamabanabaoabapabaqabarabasabatabauabavabawabaxabayabazabbbabbcabbdabbeabbfabbgabbhabbiabbjabbkabblabbmabbnabboabbpabbqabbrabbsabbtabbuabbvabbwabbxabbyabbzabcbabccabcdabceabcfabcgabchabciabcjabckabclabcmabcnabcoabcpabcqabcrabcsabctabcuabcvabcwabcxabcyabczabdbabdcabddabdeabdfabdgabdhabdiabdjabdkabdlabdmabdnabdoabdpabdqabdrabdsabdtabduabdvabdwabdxabdyabdzabebabecabedabeeabefabegabehabeiabejabekabelabemabenabeoabepabeqaberabesabetabeuabevabewabexabeyabezabfbabfcabfdabfeabffabfgabfhabfiabfjabfkabflabfmabfnabfoabfpabfqabfrabfsabftabfuabfvabfwabfxabfyabfzabgbabgcabgdabgeabgfabggabghabgiabgjabgkabglabgmabgnabgoabgpabgqabgrabgsabgtabguabgvabgwabgxabgyabgzabhbabhcabhdabheabhfabhgabhhabhiabhjabhkabhlabhmabhnabhoabhpabhqabhrabhsabhtabhuabhvabhwabhxabhyabhzabibabicabidabieabifabigabihabiiabijabikabilabimabinabioabipabiqabirabisabitabiuabivabiwabixabiyabizabjbabjcabjdabjeabjfabjgabjhabjiabjjabjkabjlabjmabjnabjoabjpabjqabjrabjsabjtabjuabjvabjwabjxabjyabjzabkbabkcabkdabkeabkfabkgabkhabkiabkjabkkabklabkmabknabkoabkpabkqabkrabksabktabkuabkvabkwabkxabkyabkzablbablcabldableablfablgablhabliabljablkabllablmablnabloablpablqablrablsabltabluablvablwablxablyablzabmbabmcabmdabmeabmfabmgabmhabmiabmjabmkabmlabmmabmnabmoabmpabmqabmrabmsabmtabmuabmvabmwabmxabmyabmzabnbabncabndabneabnfabngabnhabniabnjabnkabnlabnmabnnabnoabnpabnqabnrabnsabntabnuabnvabnwabnxabnyab...
nzabobabocabodaboeabofabogabohaboiabojabokabolabomabonabooabopaboqaborabosabotabouabovabowaboxaboyabozabpbabpcabpdabpeabpfabpgabphabpiabpjabpkabplabpmabpnabpoabppabpqabprabpsabptabpuabpvabpwabpxabpyabpzabqbabqcabqdabqeabqfabqgabqhabqiabqjabqkabqlabqmabqnabqoabqpabqqabqrabqsabqtabquabqvabqwabqxabqyabqzabrbabrcabrdabreabrfabrgabrhabriabrjabrkabrlabrmabrnabroabrpabrqabrrabrsabrtabruabrvabrwabrxabryabrzabsbabscabsdabseabsfabsgabshabsiabsjabskabslabsmabsnabsoabspabsqabsrabssabstabsuabsvabswabsxabsyabszabtbabtcabtdabteabtfabtgabthabtiabtjabtkabtlabtmabtnabtoabtpabtqabtrabtsabttabtuabtvabtwabtxabtyabtzabubabucabudabueabufabugabuhabuiabujabukabulabumabunabuoabupabuqaburabusabutabuuabuvabuwabuxabuyabuzabvbabvcabvdabveabvfabvgabvhabviabvjabvkabvlabvmabvnabvoabvpabvqabvrabvsabvtabvuabvvabvwabvxabvyabvzabwbabwcabwdabweabwfabwgabwhabwiabwjabwkabwlabwmabwnabwoabwpabwqabwrabwsabwtabwuabwvabwwabwxabwyabwzabxbabxcabxdabxeabxfabxgabxhabxiabxjabxkabxlabxmabxnabxoabxpabxqabxrabxsabxtabxuabxvabxwabxxabxyabxzabybabycabydabyeabyfabygabyhabyiabyjabykabylabymabynabyoabypabyqabyrabysabytabyuabyvabywabyxabyyabyzabzbabzcabzdabzeabzfabzgabzhabziabzjabzkabzlabzmabznabzoabzpabzqabzrabzsabztabzuabzvabzwabzxabzyabzzacacadacaeacafacagacahacaiacajacakacalacamacanacaoacapacaqacaracasacatacauacavacawacaxacayacazacbbacbcacbdacbeacbfacbgacbhacbiacbjacbkacblacbmacbnacboacbpacbqacbracbsacbtacbuacbvacbwacbxacbyacbzaccbacccaccdacceaccfaccgacchacciaccjacckacclaccmaccnaccoaccpaccqaccraccsacctaccuaccvaccwaccxaccyacczacdbacdcacddacdeacdfacdgacdhacdiacdjacdkacdlacdmacdnacdoacdpacdqacdracdsacdtacduacdvacdwacdxacdyacdzacebacecacedaceeacefacegacehaceiacejacekacelacemacenaceoacepaceqaceracesacetaceuacevacewacexaceyacezacfbacfcacfdacfeacffacfgacfhacfiacfjacfkacflacfmacfnacfoacfpacfqacfracfsacftacfuacfvacfwacfxacfyacfzacgbacgcacgdacgeacgfacggacghacgiacgjacgkacglacgmacgnacgoacgpacgqacgracgsacgtacguacgvacgwacgxacgyacgzachbachcachdacheachfachgachhachiachjachkachlachmachnachoachpachqachrachsachtachuachvachwachxachyachzacibacicacidacieacifacigacihaciiacijacikacilacimacinacioacipaciqaciracisacitaciuacivaciwacixaciyacizacjbacjcacjdacjeacjfacjgacjhacjiacjjacjkacjlacjmacjnacjoacjpacjqacjracjsacjtacjuacjvacjwacjxacjyacjzackbackcackdackeackfackgackhackiackjackkacklackmacknackoackpackqackracksacktackuackvackwackxackyackzaclbaclcacldacleaclfaclgaclhacliacljaclkacllaclmaclnacloaclpaclqaclraclsacltacluaclvaclwaclxaclyaclzacmbacmcacmdacmeacmfacmgacmhacmiacmjacmkacmlacmmacmnacmoacmpacmqacmracmsacmtacmuacmvacmwacmxacmyacmzacnbacncacndacneacnfacngacnhacniacnjacnkacnlacnmacnnacnoacnpacnqacnracnsacntacnuacnvacnwacnxacnyacnzacobacocacodacoeacofacogacohacoiacojacokacolacomaconacooacopacoqacoracosacotacouacovacowacoxacoyacozacpbacpcacpdacpeacpfacpgacphacpiacpjacpkacplacpmacpnacpoacppacpqacpracpsacptacpuacpvacpwacpxacpyacpzacqbacqcacqdacqeacqfacqgacqhacqiacqjacqkacqlacqmacqnacqoacqpacqqacqracqsacqtacquacqvacqwacqxacqyacqzacrbacrcacrdacreacrfacrgacrhacriacrjacrkacrlacrmacrnacroacrpacrqacrracrsacrtacruacrvacrwacrxacryacrzacsbacscacsdacseacsfacsgacshacsiacsjacskacslacsmacsnacsoacspacsqacsracssacstacsuacsvacswacsxacsyacszactbactcactdacteactfactgacthactiactjactkactlactmactnactoactpactqactractsacttactuactvactwactxactyactzacubacucacudacueacufacugacuhacuiacujacukaculacumacunacuoacupacuqacuracusacutacuuacuvacuwacuxacuyacuzacvbacvcacvdacveacvfacvgacvhacviacvjacvkacvlacvmacvnacvoacvpacvqacvracvsacvtacvuacvvacvwacvxacvyacvzacwbacwcacwdacweacwfacwgacwhacwiacwjacwkacwlacwmacwnacwoacwpacwqacwracwsacwtacwuacwvacwwacwxacwyacwzacxbacxcacxdacxeacxfacxgacxhacxiacxjacxkacxlacxmacxnacxoacxpacxqacxracxsacxtacxuacxvacxwacxxacxyacxzacybacycacydacyeacyfacygacyhacyiacyjacykacylacymacynacyoacypacyqacyracysacytacyuacyvacywacyxacyyacyzaczbaczcaczdaczeaczfaczgaczhacziaczjaczkaczlaczmacznaczoaczpaczqaczraczsacztaczuaczvaczwaczxaczyaczzadadaeadafadagadahadaiadajadakadaladamadanadaoadapadaqadaradasadatadauadavadawadaxadayadazadbbadbcadbdadbeadbfadbgadbhadbiadbjadbkadbladbmadbnadboadbpadbqadbradbsadbtadbuadbvadbwadbxadbyadbzadcbadccadc...
dadcea

image

% (echo '```'; cowsay moo; echo '```') | ./notify -id discord -bulk

image

@ehsandeep ehsandeep requested a review from Mzack9999 May 28, 2022 16:14
@ehsandeep ehsandeep linked an issue May 29, 2022 that may be closed by this pull request
@ehsandeep ehsandeep removed the request for review from parrasajad May 29, 2022 14:29
@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

@ehsandeep ehsandeep merged commit 74fff6e into projectdiscovery:dev May 30, 2022
@ehsandeep ehsandeep added Status: Completed Nothing further to be done with this issue. Awaiting to be closed. and removed Status: Review Needed The issue has a PR attached to it which needs to be reviewed labels May 30, 2022
justinsteven added a commit to justinsteven/notify that referenced this pull request Jun 12, 2022
Fixes projectdiscovery#134 (this was previously fixed but got backed out in landing projectdiscovery#130)
ehsandeep pushed a commit that referenced this pull request Jun 13, 2022
* Revert "Fix notify silently fails (#146)"

This reverts commit 173f914.

* Emit logged lines to stdout, not stderr

Fixes #134 (this was previously fixed but got backed out in landing #130)

* Split lines as per CharLimit in non-bulk mode

Resolves #137

* Bubble up any Scanner errors

This surfaces the error that's causing #138:

'bufio.Scanner: token too long'

* Fix infinite loop with -char-limit <= len('...')

We're using '...' to indicate that a line has been truncated. If -char-limit
was less than the length of this ellipsis string, the scanner would never
terminate.

Raise an error if the charLimit given to a splitter is <= len('...')

* Ensure we never allow the Scanner buffer to fill

We know we never need more than CharLimit chars from the Scanner in one go

First of all, we ensure that the Scanner has a buffer which can hold at least
CharLimit chars.

Then we handle cases where the Scanner wants more data but we don't need it
to get more data. Thus it should never end up in a place where its internal
buffer is filled, and it should never return bufio.ErrToLong

Fixes #138

* fmt.print => gologger

Co-authored-by: mzack <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Status: Completed Nothing further to be done with this issue. Awaiting to be closed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow -bulk mode to work with stdin notified lines are emitted to stderr, not stdout

4 participants