@@ -999,6 +999,13 @@ runs these steps:
999
999
1. Let |tail| be a [=byte sequence=] containing the last
1000
1000
|oldSize| - (|writePosition| + |data|.[=byte sequence/length=] ) bytes of |stream|.[=[[buffer]]=] .
1001
1001
1. Set |stream|.[=[[buffer]]=] to the concatenation of |head|, |data| and |tail|.
1002
+ 1. If the operations modifying |stream|.[=[[buffer]]=] in the previous steps failed
1003
+ due to exceeding the [=storage quota=] , [=/reject=] |p| with a {{QuotaExceededError}} and abort,
1004
+ leaving |stream|.[=[[buffer]]=] unmodified.
1005
+
1006
+ Note: [=Storage quota=] only applies to files stored in the [=origin private file system=] .
1007
+ However this operation could still fail for other files, for example if the disk being written
1008
+ to runs out of disk space.
1002
1009
1. Set |stream|.[=[[seekOffset]]=] to |writePosition| + |data|.[=byte sequence/length=] .
1003
1010
1. [=/Resolve=] |p|.
1004
1011
1. Else if |command| is {{WriteCommandType/"seek"}} :
@@ -1014,6 +1021,13 @@ runs these steps:
1014
1021
1. If |newSize| is larger than |oldSize|:
1015
1022
1. Set |stream|.[=[[buffer]]=] to a [=byte sequence=] formed by concating
1016
1023
|stream|.[=[[buffer]]=] with a [=byte sequence=] containing |newSize|-|oldSize| `0x00` bytes.
1024
+ 1. If the operation in the previous step failed due to exceeding the [=storage quota=] ,
1025
+ [=/reject=] |p| with a {{QuotaExceededError}} and abort,
1026
+ leaving |stream|.[=[[buffer]]=] unmodified.
1027
+
1028
+ Note: [=Storage quota=] only applies to files stored in the [=origin private file system=] .
1029
+ However this operation could still fail for other files, for example if the disk being written
1030
+ to runs out of disk space.
1017
1031
1. Else if |newSize| is smaller than |oldSize|:
1018
1032
1. Set |stream|.[=[[buffer]]=] to a [=byte sequence=] containing the first |newSize| bytes
1019
1033
in |stream|.[=[[buffer]]=] .
@@ -1748,3 +1762,24 @@ Another risk factor is that of ransomware attacks. The limitations described abo
1748
1762
blocking access to certain sensitive directories helps limit the damage such an attack can do.
1749
1763
Additionally user agents can grant write access to files at whatever granularity they deem
1750
1764
appropriate.
1765
+
1766
+ ## Filling up a users disk ## {#filling-up-disk}
1767
+
1768
+ Other than files in the [=origin private file system=] , files written by this API are not subject
1769
+ to [=storage quota=] . As such websites can fill up a users disk without being limited by
1770
+ quota, which could leave a users device in a bad state (do note that even with storage that is
1771
+ subject to [=storage quota=] it is still possible to fill up, or come close to filling up, a users
1772
+ disk, since [=storage quota=] in general is not dependent on the amount of available disk
1773
+ space).
1774
+
1775
+ Without this API websites can write data to disk not subject to quota limitations already
1776
+ by triggering downloads of large files (potentially created client side, to not incur any network
1777
+ overhead). While the presence of {{FileSystemWritableFileStream/truncate()}} and writing at a
1778
+ potentially really large offset past the end of a file makes it much easier and lower cost to
1779
+ create large files, on most file systems such files should not actually take up as much disk space as
1780
+ most commonly used file systems support sparse files (and thus wouldn't actually store the NUL
1781
+ bytes generated by resizing a file or seeking past the end of it).
1782
+
1783
+ Whatever mitigations user agents use to guard against websites filling up a disk via either
1784
+ quota managed storage or the existing downloads mechanism should also be employed when websites
1785
+ use this API to write to disk.
0 commit comments