anon-iclr-submission/benchname-bug-localization huggingface dataset:
Repository: spesmilo/electrum
Issue: Electrum 3.0 crashes when signing transactions with Ledger

For the first time, I used my ledger nano s to send BTC using electrum but after pressing confirm on the device, Electrum freezes and doesn't respond. I tried on both MacOs and Win7, with the same exact behaviour, both running v3.0.1. I encountered no problems when using the ledger wallet.

Changed files:
plugins/ledger/ledger.py

diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py
index a1849bcdd..c323d684b 100644
--- a/plugins/ledger/ledger.py
+++ b/plugins/ledger/ledger.py
@@ -238,7 +238,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
         except Exception as e:
             self.give_error(e, True)
         finally:
-            self.handler.clear_dialog()
+            self.handler.finished()
         self.signing = False
         # Parse the ASN.1 signature
         rLength = signature[3]
@@ -376,13 +376,13 @@ class Ledger_KeyStore(Hardware_KeyStore):
                 transactionOutput = outputData['outputData']
                 if outputData['confirmationNeeded']:
                     outputData['address'] = output
-                    self.handler.clear_dialog()
+                    self.handler.finished()
                     pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin
                     if not pin:
                         raise UserWarning()
                     if pin != 'paired':
                         self.handler.show_message(_("Confirmed. Signing Transaction..."))
-                while inputIndex < len(inputs):                
+                while inputIndex < len(inputs):
                     singleInput = [ chipInputs[inputIndex] ]
                     self.get_client().startUntrustedTransaction(False, 0,
                                                             singleInput, redeemScripts[inputIndex])
@@ -400,7 +400,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
                         transactionOutput = outputData['outputData']
                     if outputData['confirmationNeeded']:
                         outputData['address'] = output
-                        self.handler.clear_dialog()
+                        self.handler.finished()
                         pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin
                         if not pin:
                             raise UserWarning()
@@ -421,7 +421,7 @@ class Ledger_KeyStore(Hardware_KeyStore):
             traceback.print_exc(file=sys.stdout)
             self.give_error(e, True)
         finally:
-            self.handler.clear_dialog()
+            self.handler.finished()
 
         for i, txin in enumerate(tx.inputs()):
             signingPos = inputs[i][4]
Repository: spesmilo/electrum
Issue: PermissionError: [Errno 13] Permission denied: '/var/www/html/r/req/d'


Crash Report
============

This crash report was reported through the automatic crash reporting system 🤖

Traceback
--------------

```Python traceback
  File "/home/user/wspace/electrum/gui/qt/main_window.py", line 907, in save_payment_request
    self.wallet.add_payment_request(req, self.config)
  File "/home/user/wspace/electrum/lib/wallet.py", line 1563, in add_payment_request
    os.makedirs(path)
  File "/usr/lib/python3.5/os.py", line 231, in makedirs
    makedirs(head, mode, exist_ok)
  File "/usr/lib/python3.5/os.py", line 231, in makedirs
    makedirs(head, mode, exist_ok)
  File "/usr/lib/python3.5/os.py", line 241, in makedirs
    mkdir(name, mode)

PermissionError: [Errno 13] Permission denied: '/var/www/html/r/req/d'
```

Reporter
------------

This issue was reported by 1 user(s):

| Electrum Version  | Operating System  | Wallet Type  | Locale |
|---|---|---|---|
| 3.1  | Linux-4.9.0-3-amd64-x86_64-with-debian-9.3 | standard | en_GB |


Additional Information
------------------------

The reporting user(s) did not provide additional information.

Changed files:
gui/qt/main_window.py

diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py
index 480d67fa5..ddaafc4b7 100644
--- a/gui/qt/main_window.py
+++ b/gui/qt/main_window.py
@@ -904,11 +904,17 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, PrintError):
         i = self.expires_combo.currentIndex()
         expiration = list(map(lambda x: x[1], expiration_values))[i]
         req = self.wallet.make_payment_request(addr, amount, message, expiration)
-        self.wallet.add_payment_request(req, self.config)
-        self.sign_payment_request(addr)
-        self.request_list.update()
-        self.address_list.update()
-        self.save_request_button.setEnabled(False)
+        try:
+            self.wallet.add_payment_request(req, self.config)
+        except Exception as e:
+            traceback.print_exc(file=sys.stderr)
+            self.show_error(_('Error adding payment request') + ':\\n' + str(e))
+        else:
+            self.sign_payment_request(addr)
+            self.save_request_button.setEnabled(False)
+        finally:
+            self.request_list.update()
+            self.address_list.update()
 
     def view_and_paste(self, title, msg, data):
         dialog = WindowModalDialog(self, title)
Repository: spesmilo/electrum
Issue: cant access electrum

I made a payment of bitcoin using coingate to buy tokens with bitcoin. 
Now, when I try to open it, Electrum will crash when I enter the correct password. Any incorrect password will show me an alert that it's incorrect (and I am very certain that I have the right password).
The wallet is encrypted. 
I had version 3.0.2 , now updated to 3.0.5 ,but still can t access
any ideas of what might be happening? it was working fine until before this payment

Changed files:
lib/wallet.py

diff --git a/lib/wallet.py b/lib/wallet.py
index a9dc646bc..8366e8c62 100644
--- a/lib/wallet.py
+++ b/lib/wallet.py
@@ -367,7 +367,8 @@ class Abstract_Wallet(PrintError):
     def add_unverified_tx(self, tx_hash, tx_height):
         if tx_height == 0 and tx_hash in self.verified_tx:
             self.verified_tx.pop(tx_hash)
-            self.verifier.merkle_roots.pop(tx_hash, None)
+            if self.verifier:
+                self.verifier.merkle_roots.pop(tx_hash, None)
 
         # tx will be verified only if height > 0
         if tx_hash not in self.verified_tx:
Repository: spesmilo/electrum
Issue: Cannot create a new wallet with a Ledger Nano S

Version: 3.0.2
OS: Windows 10
Ledger Nano S

Trying to create a new wallet:

1. Standard Wallet
2. Use Hardware Device
3. An unnamed ledger [ledger, initialized]
4. **Read Error**

Ledger is in the Bitcoin app, with "Browser Support" turned to "No".

Any other details or logs I can provide?

Changed files:
lib/base_wizard.py, lib/plugins.py, plugins/ledger/ledger.py

diff --git a/lib/base_wizard.py b/lib/base_wizard.py
index b73e19537..ab18b7617 100644
--- a/lib/base_wizard.py
+++ b/lib/base_wizard.py
@@ -234,6 +234,15 @@ class BaseWizard(object):
         self.plugin = self.plugins.get_plugin(name)
         try:
             self.plugin.setup_device(device_info, self, purpose)
+        except OSError as e:
+            self.show_error(_('We encountered an error while connecting to your device:')
+                            + '\\n' + str(e) + '\\n'
+                            + _('To try to fix this, we will now re-pair with your device.') + '\\n'
+                            + _('Please try again.'))
+            devmgr = self.plugins.device_manager
+            devmgr.unpair_id(device_info.device.id_)
+            self.choose_hw_device(purpose)
+            return
         except BaseException as e:
             self.show_error(str(e))
             self.choose_hw_device(purpose)
diff --git a/lib/plugins.py b/lib/plugins.py
index e37fe08a5..e94013a24 100644
--- a/lib/plugins.py
+++ b/lib/plugins.py
@@ -362,15 +362,20 @@ class DeviceMgr(ThreadJob, PrintError):
             if not xpub in self.xpub_ids:
                 return
             _id = self.xpub_ids.pop(xpub)
-        client = self.client_lookup(_id)
-        self.clients.pop(client, None)
-        if client:
-            client.close()
+            self._close_client(_id)
 
     def unpair_id(self, id_):
         xpub = self.xpub_by_id(id_)
         if xpub:
             self.unpair_xpub(xpub)
+        else:
+            self._close_client(id_)
+
+    def _close_client(self, id_):
+        client = self.client_lookup(id_)
+        self.clients.pop(client, None)
+        if client:
+            client.close()
 
     def pair_xpub(self, xpub, id_):
         with self.lock:
diff --git a/plugins/ledger/ledger.py b/plugins/ledger/ledger.py
index 4e181c4f7..cf56ee973 100644
--- a/plugins/ledger/ledger.py
+++ b/plugins/ledger/ledger.py
@@ -172,6 +172,10 @@ class Ledger_Client():
                 raise Exception("Dongle is temporarily locked - please unplug it and replug it again")
             if ((e.sw & 0xFFF0) == 0x63c0):
                 raise Exception("Invalid PIN - please unplug the dongle and plug it again before retrying")
+            if e.sw == 0x6f00 and e.message == 'Invalid channel':
+                # based on docs 0x6f00 might be a more general error, hence we also compare message to be sure
+                raise Exception("Invalid channel.\\n"
+                                "Please make sure that 'Browser support' is disabled on your device.")
             raise e
 
     def checkDevice(self):
Repository: spesmilo/electrum
Issue: Cannot access Trezor Model T with passphrases enabled

Using the latest electrum and trezorlib code, the Trezor Model T works in Electrum as long as passphrases are not enabled.

If passphrases are enabled, then the device asks you to choose whether to enter the passphrase on the device or the "host" (i.e. Electrum).
-If you choose to enter the passphrase on the device, the device screen goes blank and Electrum shows a prompt for a passphrase. When anything is entered Electrum gives an error: "Passphrase entered when it should not be"
-if you choose to enter the passphrase on the host. the device shows "Please type passphrase on connected host" and Electrum shows a prompt for a passphrase.  When anything is entered Electrum gives an error: "Got <class 'trezorlib.messages.PassphraseStateRequest.PassphraseStateRequest>, expected (<class ' trezorlib.messages.PublicKey.PublicKey'>,)"

I am able to use trezorlib directly to get addresses from the device while passphrases are enabled, in which case passphrases are correctly accepted on either the device or host as per the user's choice.

Changed files:
plugins/trezor/clientbase.py

diff --git a/plugins/trezor/clientbase.py b/plugins/trezor/clientbase.py
index 687d31c4d..6e10d4c49 100644
--- a/plugins/trezor/clientbase.py
+++ b/plugins/trezor/clientbase.py
@@ -55,6 +55,9 @@ class GuiMixin(object):
         return self.proto.PinMatrixAck(pin=pin)
 
     def callback_PassphraseRequest(self, req):
+        if req and hasattr(req, 'on_device') and req.on_device is True:
+            return self.proto.PassphraseAck()
+
         if self.creating_wallet:
             msg = _("Enter a passphrase to generate this wallet.  Each time "
                     "you use this wallet your {} will prompt you for the "
@@ -68,6 +71,9 @@ class GuiMixin(object):
         passphrase = bip39_normalize_passphrase(passphrase)
         return self.proto.PassphraseAck(passphrase=passphrase)
 
+    def callback_PassphraseStateRequest(self, msg):
+        return self.proto.PassphraseStateAck()
+
     def callback_WordRequest(self, msg):
         self.step += 1
         msg = _("Step {}/24.  Enter seed word as explained on "
Repository: spesmilo/electrum
Issue: Lightning Channels Back Up Missing

<!-- Note: This website is for bug reports, not general questions.
Do not post issues about non-bitcoin versions of Electrum. -->

After saving a backup from my wallet where I have a Lightning Channel Opened, I restored the backup in another place (File.backup)

All other things worked correctly, all my labels were restored etc but none of the lightning channels were stored and I don't know where to find that option

Shouldn't this automatically save all Lightning BackUps? or at least, allow us to save those backups separately?
Nico

Changed files:
electrum/wallet_db.py, electrum/wallet.py

diff --git a/electrum/wallet.py b/electrum/wallet.py
index d29ef98bc..3ea1d2c23 100644
--- a/electrum/wallet.py
+++ b/electrum/wallet.py
@@ -318,7 +318,7 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
         new_db = WalletDB(self.db.dump(), manual_upgrades=False)
 
         if self.lnworker:
-            channel_backups = new_db.get_dict('channel_backups')
+            channel_backups = new_db.get_dict('imported_channel_backups')
             for chan_id, chan in self.lnworker.channels.items():
                 channel_backups[chan_id.hex()] = self.lnworker.create_channel_backup(chan_id)
             new_db.put('channels', None)
diff --git a/electrum/wallet_db.py b/electrum/wallet_db.py
index 3a602c36d..e6c08f102 100644
--- a/electrum/wallet_db.py
+++ b/electrum/wallet_db.py
@@ -53,7 +53,7 @@ if TYPE_CHECKING:
 
 OLD_SEED_VERSION = 4        # electrum versions < 2.0
 NEW_SEED_VERSION = 11       # electrum versions >= 2.0
-FINAL_SEED_VERSION = 40     # electrum >= 2.7 will set this to prevent
+FINAL_SEED_VERSION = 41     # electrum >= 2.7 will set this to prevent
                             # old versions from overwriting new format
 
 
@@ -189,6 +189,7 @@ class WalletDB(JsonDB):
         self._convert_version_38()
         self._convert_version_39()
         self._convert_version_40()
+        self._convert_version_41()
         self.put('seed_version', FINAL_SEED_VERSION)  # just to be sure
 
         self._after_upgrade_tasks()
@@ -811,6 +812,15 @@ class WalletDB(JsonDB):
                 ks['seed_type'] = seed_type
         self.data['seed_version'] = 40
 
+    def _convert_version_41(self):
+        # this is a repeat of upgrade 39, to fix wallet backup files (see #7339)
+        if not self._is_upgrade_method_needed(40, 40):
+            return
+        imported_channel_backups = self.data.pop('channel_backups', {})
+        imported_channel_backups.update(self.data.get('imported_channel_backups', {}))
+        self.data['imported_channel_backups'] = imported_channel_backups
+        self.data['seed_version'] = 41
+
     def _convert_imported(self):
         if not self._is_upgrade_method_needed(0, 13):
             return
Repository: spesmilo/electrum
Issue: problem with swaps on 4.0.6

<!-- Note: This website is for bug reports, not general questions.
Do not post issues about non-bitcoin versions of Electrum. -->
i noticed that when creating a swap, the OK button remains always not working even if all parameters are correctly in place. I'm doing same exactly operation with version 4.0.5 all is going fine.

Changed files:
electrum/gui/qt/swap_dialog.py

diff --git a/electrum/gui/qt/swap_dialog.py b/electrum/gui/qt/swap_dialog.py
index 3b8a1d107..5adcd77fd 100644
--- a/electrum/gui/qt/swap_dialog.py
+++ b/electrum/gui/qt/swap_dialog.py
@@ -34,7 +34,7 @@ class SwapDialog(WindowModalDialog):
         self.lnworker = self.window.wallet.lnworker
         self.swap_manager = self.lnworker.swap_manager
         self.network = window.network
-        self.tx = None
+        self.tx = None  # for the forward-swap only
         self.is_reverse = True
         vbox = QVBoxLayout(self)
         self.description_label = WWLabel(self.get_description())
@@ -113,7 +113,6 @@ class SwapDialog(WindowModalDialog):
             else:
                 self._spend_max_forward_swap()
         else:
-            self.tx = None
             self.send_amount_e.setAmount(None)
         self.update_fee()
 
@@ -156,7 +155,8 @@ class SwapDialog(WindowModalDialog):
         self.recv_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
         self.recv_amount_e.follows = False
         self.send_follows = False
-        self.ok_button.setEnabled((recv_amount is not None) and (self.tx is not None))
+        self.ok_button.setEnabled((recv_amount is not None)
+                                  and (self.tx is not None or self.is_reverse))
 
     def on_recv_edited(self):
         if self.recv_amount_e.follows:
@@ -171,7 +171,8 @@ class SwapDialog(WindowModalDialog):
         self.send_amount_e.setStyleSheet(ColorScheme.BLUE.as_stylesheet())
         self.send_amount_e.follows = False
         self.send_follows = True
-        self.ok_button.setEnabled((send_amount is not None) and (self.tx is not None))
+        self.ok_button.setEnabled((send_amount is not None)
+                                  and (self.tx is not None or self.is_reverse))
 
     def update(self):
         sm = self.swap_manager
@@ -188,6 +189,7 @@ class SwapDialog(WindowModalDialog):
         self.update_fee()
 
     def update_fee(self):
+        self.tx = None
         is_max = self.max_button.isChecked()
         if self.is_reverse:
             if is_max:
@@ -201,8 +203,8 @@ class SwapDialog(WindowModalDialog):
                 onchain_amount = self.send_amount_e.get_amount()
                 self.update_tx(onchain_amount)
             fee = self.tx.get_fee() if self.tx else None
-        if self.tx is None:
-            self.ok_button.setEnabled(False)
+            if self.tx is None:
+                self.ok_button.setEnabled(False)
         fee_text = self.window.format_amount(fee) + ' ' + self.window.base_unit() if fee else ''
         self.fee_label.setText(fee_text)
         self.fee_label.repaint()  # macOS hack for #6269
Repository: spesmilo/electrum
Issue: partial txn format uses only 2 bytes for derivation path index. overflow

https://github.com/spesmilo/electrum/blob/468c35e60548e82c22f1d276cbeb9f9855b79f75/electrum/keystore.py#L299-L304

In BIP32, path indices are allocated 4 bytes, but our custom partial transaction serialization format only allocated 2 bytes.
This effectively means that wallets with over 65535 addresses cannot spend some of their UTXOs.

Changed files:
electrum/tests/test_transaction.py, electrum/keystore.py

diff --git a/electrum/keystore.py b/electrum/keystore.py
index 30a803f0b..49f032dc6 100644
--- a/electrum/keystore.py
+++ b/electrum/keystore.py
@@ -282,7 +282,13 @@ class Xpub:
         return node.eckey.get_public_key_hex(compressed=True)
 
     def get_xpubkey(self, c, i):
-        s = ''.join(map(lambda x: bitcoin.int_to_hex(x,2), (c, i)))
+        def encode_path_int(path_int) -> str:
+            if path_int < 0xffff:
+                hex = bitcoin.int_to_hex(path_int, 2)
+            else:
+                hex = 'ffff' + bitcoin.int_to_hex(path_int, 4)
+            return hex
+        s = ''.join(map(encode_path_int, (c, i)))
         return 'ff' + bh2u(bitcoin.DecodeBase58Check(self.xpub)) + s
 
     @classmethod
@@ -296,11 +302,14 @@ class Xpub:
         # derivation:
         dd = pk[78:]
         s = []
-        # FIXME: due to an oversight, levels in the derivation are only
-        # allocated 2 bytes, instead of 4 (in bip32)
         while dd:
-            n = int(bitcoin.rev_hex(bh2u(dd[0:2])), 16)
+            # 2 bytes for derivation path index
+            n = int.from_bytes(dd[0:2], byteorder="little")
             dd = dd[2:]
+            # in case of overflow, drop these 2 bytes; and use next 4 bytes instead
+            if n == 0xffff:
+                n = int.from_bytes(dd[0:4], byteorder="little")
+                dd = dd[4:]
             s.append(n)
         assert len(s) == 2
         return xkey, s
diff --git a/electrum/tests/test_transaction.py b/electrum/tests/test_transaction.py
index b92e1e823..a83e0223b 100644
--- a/electrum/tests/test_transaction.py
+++ b/electrum/tests/test_transaction.py
@@ -838,6 +838,11 @@ class TestTransactionTestnet(TestCaseForTestnet):
         txid = 'ba5c88e07a4025a39ad3b85247cbd4f556a70d6312b18e04513c7cec9d45d6ac'
         self._run_naive_tests_on_tx(raw_tx, txid)
 
+    def test_txid_partial_issue_5366(self):
+        raw_tx = '45505446ff000200000000010127523d70642dabd999fb43191ff6763f5b04150ba4cf38d2cfb53edf6a40ac4f0100000000fdffffff013286010000000000160014e79c7ac0b390a9caf52dc002e1095a5fbc042a18feffffffffa08601000000000000000201ff57ff045f1cf60157e9eb7a8000000038fa0b3a9c155ff3390ca0d639783d97af3b3bf66ebb69a31dfe8317fae0a7fe0324bc048fc0002253dfec9d6299711d708175f950ecee8e09db3518a5685741830000ffffcf01010043281700'
+        txid = 'a0c159616073dc7a4a482092dab4e8516c83dddb769b65919f23f6df63d33eb8'
+        self._run_naive_tests_on_tx(raw_tx, txid)
+
 # end partial txns <---
Repository: spesmilo/electrum
Issue: Description in coin tab does not update properly

Expected behaviour:
When you change address description under addresses tab, it is expected that the same description is changed under Coins tab

Current behaviour
When you change address description under addresses tab, it is expected that the same description is changed under Coins tab which does not happen. You need to close electrum and start it all over and only then the description will be updated to the new value


Changed files:
electrum/gui/qt/history_list.py

diff --git a/electrum/gui/qt/history_list.py b/electrum/gui/qt/history_list.py
index f5cefa6de..748dbf123 100644
--- a/electrum/gui/qt/history_list.py
+++ b/electrum/gui/qt/history_list.py
@@ -217,6 +217,7 @@ class HistoryModel(QAbstractItemModel, PrintError):
         tx_item['label'] = self.parent.wallet.get_label(tx_item['txid'])
         topLeft = bottomRight = self.createIndex(row, 2)
         self.dataChanged.emit(topLeft, bottomRight, [Qt.DisplayRole])
+        self.parent.utxo_list.update()
 
     def get_domain(self):
         '''Overridden in address_dialog.py'''
Repository: spesmilo/electrum
Issue: Electrum 3.2.3: "Incorrect Password" when manual typing, works fine when pasting from clipboard

My password works ok when copying and pasting it, but fails with "Incorrect Password" when manually typing it. I've confirmed that the password being typed is correct by using `xdotool` to type it over the GUI, so there's no human error here.

I managed to narrow the problem a bit: **A password with special characters (á, ã, é and so on) does not work when manual typed.**

This applies to the Wizard, Change Password box, Seed "Enter Password" box, probably all over the GUI.

I'm using Arch Linux with `gnome-shell` 3.30.1

-- Edit --
I managed to narrow it down further: apparently the bug only happens if the password was set up by copying and pasting it on the first place. So, to reproduce the bug:

- Open any wallet
- Open the Change Password dialog
- Paste `á` (from the clipboard) into *New Password* and *Confirm Password* input boxes and change the password
- Open any password dialog (you can open Change Password again)
- Type `á` with the keyboard and submit the dialog, you'll get Invalid Password.
- Paste `á` from the clipboard, it'll work.

Changed files:
electrum/gui/qt/password_dialog.py

diff --git a/electrum/gui/qt/password_dialog.py b/electrum/gui/qt/password_dialog.py
index 3202618ec..c38251d94 100644
--- a/electrum/gui/qt/password_dialog.py
+++ b/electrum/gui/qt/password_dialog.py
@@ -56,19 +56,22 @@ def check_password_strength(password):
 PW_NEW, PW_CHANGE, PW_PASSPHRASE = range(0, 3)
 
 
+class PasswordLineEdit(QLineEdit):
+    # workaround Qt bug https://github.com/spesmilo/electrum/issues/5038
+    def __init__(self, *args, **kwargs):
+        QLineEdit.__init__(self, *args, **kwargs)
+        self.textChanged.connect(lambda: self.setEchoMode(2))
+
+
 class PasswordLayout(object):
 
     titles = [_("Enter Password"), _("Change Password"), _("Enter Passphrase")]
 
     def __init__(self, msg, kind, OK_button, wallet=None, force_disable_encrypt_cb=False):
         self.wallet = wallet
-
-        self.pw = QLineEdit()
-        self.pw.setEchoMode(2)
-        self.new_pw = QLineEdit()
-        self.new_pw.setEchoMode(2)
-        self.conf_pw = QLineEdit()
-        self.conf_pw.setEchoMode(2)
+        self.pw = PasswordLineEdit()
+        self.new_pw = PasswordLineEdit()
+        self.conf_pw = PasswordLineEdit()
         self.kind = kind
         self.OK_button = OK_button
 
@@ -288,8 +291,7 @@ class PasswordDialog(WindowModalDialog):
     def __init__(self, parent=None, msg=None):
         msg = msg or _('Please enter your password')
         WindowModalDialog.__init__(self, parent, _("Enter Password"))
-        self.pw = pw = QLineEdit()
-        pw.setEchoMode(2)
+        self.pw = pw = PasswordLineEdit()
         vbox = QVBoxLayout()
         vbox.addWidget(QLabel(msg))
         grid = QGridLayout()
Repository: sqlfluff/sqlfluff
Issue: [L016] Applying rule L016 threw an Exception: tuple index out of range 



No errors during `sqlfluff parse` only error during `lint` and `fix`
I do not have a sql script that I can share (hopefully I can create a script that i can share). However the detail is as follows:

- Had CTE (with blocks and alias)
- Long sql statements (select, where, order by, etc.)
- Sql selected one column per line


## Expected Behaviour
`L:  1 | P: 177 | L016 | Line is too long`
## Observed Behaviour
Error 

```python
CRITICAL   [L016] Applying rule L016 threw an Exception: tuple index out of range 
Traceback (most recent call last):
  File "/Users/<username>/.local/pipx/venvs/sqlfluff/lib/python3.9/site-packages/sqlfluff/core/rules/base.py", line 290, in crawl
    res = self._eval(
  File "/Users/<username>/.local/pipx/venvs/sqlfluff/lib/python3.9/site-packages/sqlfluff/core/rules/std/L016.py", line 437, in _eval
    fixes = self._eval_line_for_breaks(this_line)
  File "/Users/<username>/.local/pipx/venvs/sqlfluff/lib/python3.9/site-packages/sqlfluff/core/rules/std/L016.py", line 274, in _eval_line_for_breaks
    self.logger.info("    {0}: {1!r}".format(idx, sec))
  File "/Users/<username>/.local/pipx/venvs/sqlfluff/lib/python3.9/site-packages/sqlfluff/core/rules/std/L016.py", line 56, in __repr__
    pos=self.segments[0].get_start_pos_marker(),
IndexError: tuple index out of range
== [views/v_gre_susp.sql] FAIL
```

`L:  1 | P: 177 | L016 | Unexpected exception: tuple index out of range; Could you open an issue at https://github.com/sqlfluff/sqlfluff/issues ? You can  ignore this exception for now, by adding '--noqa: L016' at the end of line 15`
## Steps to Reproduce

## Version
sqlfluff, version 0.5.0

## Configuration
```
No custom configuration. Running out of the box with ansi dialect
```


Changed files:
src/sqlfluff/core/rules/std/L016.py

diff --git a/src/sqlfluff/core/rules/std/L016.py b/src/sqlfluff/core/rules/std/L016.py
index f1e7b762..98cfa4b5 100644
--- a/src/sqlfluff/core/rules/std/L016.py
+++ b/src/sqlfluff/core/rules/std/L016.py
@@ -53,7 +53,9 @@ class Rule_L016(Rule_L003):
                     indent_balance=self.indent_balance,
                     indent_impulse=self.indent_impulse,
                     segments="".join(elem.raw for elem in self.segments),
-                    pos=self.segments[0].get_start_pos_marker(),
+                    pos=self.segments[0].get_start_pos_marker()
+                    if self.segments
+                    else "",
                 )
 
             @property
@@ -334,9 +336,10 @@ class Rule_L016(Rule_L003):
 
         fixes = []
         for split, indent in split_at:
-            fixes += split.generate_fixes_to_coerce(
-                segments, indent_section, self, indent
-            )
+            if split.segments:
+                fixes += split.generate_fixes_to_coerce(
+                    segments, indent_section, self, indent
+                )
 
         self.logger.info("Fixes: %s", fixes)
Repository: sqlfluff/sqlfluff
Issue: Bogus capitalization warning involving SAFE_CAST, NULL, and AS

Input #1 :
```
SELECT
    SAFE_CAST(NULL AS STRING) AS age_label
FROM
    `table`
```

Input #2:
```
SELECT
    NULL AS age_label
FROM
    `table`
```

Either of these files results in a similar warning:
```
$ sqlfluff lint --exclude-rules L001 --dialect bigquery test2.sql
== [test2.sql] FAIL
L:   2 | P:  34 | L014 | Inconsistent capitalisation of unquoted identifiers.
```

I'm not sure if the `SAFE_CAST` is important or not, but am including it in case it's a different parsing pattern, etc.

@alanmcruickshank: I'd be happy to work on some tickets if you'd like to suggest any (this one or others)! February was busy for me, but I'm starting to have some discretionary time again.

Changed files:
src/sqlfluff/dialects/dialect_ansi.py, test/rules_std_test.py

diff --git a/src/sqlfluff/dialects/dialect_ansi.py b/src/sqlfluff/dialects/dialect_ansi.py
index 5834c196..4432b171 100644
--- a/src/sqlfluff/dialects/dialect_ansi.py
+++ b/src/sqlfluff/dialects/dialect_ansi.py
@@ -89,7 +89,7 @@ ansi_dialect.add(
     # also use a regex to explicitly exclude disallowed keywords.
     NakedIdentifierSegment=ReSegment.make(
         r"[A-Z0-9_]*[A-Z][A-Z0-9_]*", name='identifier', type='naked_identifier',
-        _anti_template=r"^(SELECT|JOIN|ON|USING|CROSS|INNER|LEFT|RIGHT|OUTER|INTERVAL|CASE|FULL)$"),
+        _anti_template=r"^(SELECT|JOIN|ON|USING|CROSS|INNER|LEFT|RIGHT|OUTER|INTERVAL|CASE|FULL|NULL)$"),
     FunctionNameSegment=ReSegment.make(r"[A-Z][A-Z0-9_]*", name='function_name', type='function_name'),
     # Maybe data types should be more restrictive?
     DatatypeIdentifierSegment=ReSegment.make(r"[A-Z][A-Z0-9_]*", name='data_type_identifier', type='data_type_identifier'),
@@ -206,7 +206,10 @@ ansi_dialect.add(
     LiteralGrammar=OneOf(
         Ref('QuotedLiteralSegment'), Ref('NumericLiteralSegment'),
         Ref('BooleanLiteralGrammar'), Ref('QualifiedNumericLiteralSegment'),
-        Ref('IntervalLiteralSegment')
+        Ref('IntervalLiteralSegment'),
+        # NB: Null is included in the literals, because it is a keyword which
+        # can otherwise be easily mistaken for an identifier.
+        Ref('NullKeywordSegment')
     ),
 )
 
diff --git a/test/rules_std_test.py b/test/rules_std_test.py
index 8acee7a1..c5ef40b0 100644
--- a/test/rules_std_test.py
+++ b/test/rules_std_test.py
@@ -84,6 +84,9 @@ def assert_rule_pass_in_sql(code, sql, configs=None):
     # Test that fixes are consistent
     ('L014', 'fail', 'SELECT a,   B', 'SELECT a,   b', None),
     ('L014', 'fail', 'SELECT B,   a', 'SELECT B,   A', None),
+    # Test that NULL is classed as a keyword and not an identifier
+    ('L014', 'pass', 'SELECT NULL,   a', None, None),
+    ('L010', 'fail', 'SELECT null,   a', 'SELECT NULL,   a', None),
     # Test that we don't fail * operators in brackets
     ('L006', 'pass', 'SELECT COUNT(*) FROM tbl\\n', None, None),
     # Long lines (with config override)
Repository: sqlfluff/sqlfluff
Issue: Lint API breaks if no violations


Just a quick test of the new API reveals an edge case we did not consider!

```python
from sqlfluff.api import lint

sql = """
select * from t
"""

print(lint(sql, dialect="ansi"))

# IndexError: list index out of range

```


This is on the brand new 0.4.0, and is due to this line in simple.py: https://github.com/sqlfluff/sqlfluff/blob/9f3bcdc91037157a2ea4ae988ff04922eea66b21/src/sqlfluff/api/simple.py#L36

When there are no errors, the records is an empty list and thus accessing [0] is a problem. I will fix this!

Changed files:
src/sqlfluff/api/simple.py, test/api/simple_test.py

diff --git a/src/sqlfluff/api/simple.py b/src/sqlfluff/api/simple.py
index bfa1aad4..4b143db8 100644
--- a/src/sqlfluff/api/simple.py
+++ b/src/sqlfluff/api/simple.py
@@ -33,7 +33,7 @@ def lint(sql, dialect="ansi", rules=None):
     result = linter.lint_string_wrapped(sql)
     result_records = result.as_records()
     # Return just the violations for this file
-    return result_records[0]["violations"]
+    return [] if not result_records else result_records[0]["violations"]
 
 
 def fix(sql, dialect="ansi", rules=None):
diff --git a/test/api/simple_test.py b/test/api/simple_test.py
index a47e9046..9d370b65 100644
--- a/test/api/simple_test.py
+++ b/test/api/simple_test.py
@@ -3,7 +3,6 @@
 import io
 
 import sqlfluff
-
 from sqlfluff.core.linter import ParsedString
 
 my_bad_query = "SeLEct  *, 1, blah as  fOO  from myTable"
@@ -66,6 +65,12 @@ lint_result = [
 ]
 
 
+def test__api__lint_string_without_violations():
+    """Check lint functionality when there is no violation."""
+    result = sqlfluff.lint("select column from table\\n")
+    assert result == []
+
+
 def test__api__lint_string():
     """Basic checking of lint functionality."""
     result = sqlfluff.lint(my_bad_query)