Bleed-over is not normal in Scrum. If the entire team finishes early, complete the sprint and create a new one, don’t drag in more work unless the entire team can agree it will finish within the original timebox. Each sprint has a definition of done, and if you’re not going to deliver it, you’ve got to end the sprint and start a new one, you can’t change things mid-sprint and expect everything to run just fine. The biggest problem I see in practice, and Jira encourages this, are tasks assigned to specific individuals such that the team doesn’t feel empowered to take on sprint tasks “assigned” to other people. In reality, the entire team is assigned the entire scrum, and you can’t ever take pride in finishing “your tasks” early unless your team’s tasks have finished early too! I get it, though, there’s a difference between idealized scrum and what most companies implement using Jira. That’s definitely still a problem to look into, but I can only put half the blame at best on the tool itself. If the tool didn’t have flexibility to fit to any process, folks would just pick another tool that does. Jira is simply the least such a tool could do, it’s up to you to figure out the better process for your team... and Scrum is the least-worst process I’ve encountered so far.
True, bleed-over is not "normal", but I'd bet it's common. It's a sign that you're not doing scrum "properly". My own elevator pitch for kanban to other teams still in the scrum world is: if you're not having problems, then don't switch, but if you're having problems (some of which include bleed-over, some of which include long meetings) give kanban a shot. Some teams have switched back after trying kanban, too, it's not for every team anymore than any other process or tool is.
You could also say to switch up what scrum means if you're having trouble -- to be honest I've never considered the idea of just ending the sprint early (and rescheduling the sprint planning meeting!), I'm skeptical than any of the "Certified Scrum Masters" I know have either... But it still can't be done if you are finished early but the rest of the team isn't. My team didn't really have a problem with taking on work assigned to someone else so long as that work wasn't started yet, but things get tricky when all the work assigned has been started by someone. A solution in that case does present itself besides just bringing in something new, it's the same solution as kanban when the buckets are full: join another developer on their story and pair (doesn't have to be "formal" pairing even) to get it done faster.
But you've highlighted another problem with the whole mess, that being ownership accountability. Lack of visibility outside of the standup meeting into what Dev B is working on when they're paring with Dev A (who is the sole "assigned dev" in the tracking system) is an obstacle to incentivizing pairing. Sometimes you need that visibility. On an old team I left because of terrible management, there were just two of us devs at one point. One sprint it turned out that my face was on the dev column for almost all the items, the sprint before it was my coworker's face, in reality we paired on almost everything. But that second week my manager (who never joined our standups) asked "What are your thoughts about Dev A's work performance? You seem to be doing everything right now." Management memory was sprint-to-sprint. This isn't a problem with scrum, of course, though it does enable that problem to surface where at least in a kanban style you'd have the giant column of closed things having a mix of faces.
What I have seen mostly, is that the devs finish early (about 1/2 or 3/4 into the sprint), and wait for QA. And so, QA is idle at the start of the sprint. Bleed-over was then just accepted and incorporated, while I was not sure of the usefulness of "sprints" anymore.