about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2025-01-16 19:34:58 +0100
committerbptato <nincsnevem662@gmail.com>2025-01-16 19:34:58 +0100
commit6db302e2a3c33f28f33c1044873f6bed958d2a37 (patch)
treeff2ca83dc27fe4dc4fde29e8d52064fb3f500dd4 /src
parent557ce43c0805bb8ef0c9ba4415cdf0c896625bf4 (diff)
downloadchawan-6db302e2a3c33f28f33c1044873f6bed958d2a37.tar.gz
env, dom: add crypto.getRandomValues, HTMLInputElement.files
Diffstat (limited to 'src')
-rw-r--r--src/html/dom.nim13
-rw-r--r--src/html/env.nim17
-rw-r--r--src/html/formdata.nim8
-rw-r--r--src/local/client.nim2
-rw-r--r--src/server/buffer.nim7
-rw-r--r--src/version.nim2
6 files changed, 35 insertions, 14 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index c20401eb..0f51fbef 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -92,6 +92,7 @@ type
     history* {.jsget.}: History
     localStorage* {.jsget.}: Storage
     sessionStorage* {.jsget.}: Storage
+    crypto* {.jsget.}: Crypto
     settings*: EnvironmentSettings
     loader*: FileLoader
     location* {.jsget.}: Location
@@ -111,7 +112,6 @@ type
     imageId: int
     # list of streams that must be closed for canvas rendering on load
     pendingCanvasCtls*: seq[CanvasRenderingContext2D]
-    urandom*: PosixStream
     imageTypes*: Table[string, string]
     userAgent*: string
     referrer* {.jsget.}: string
@@ -134,6 +134,9 @@ type
   Storage* = object
     map*: seq[tuple[key, value: string]]
 
+  Crypto* = object
+    urandom*: PosixStream
+
   NamedNodeMap = ref object
     element: Element
     attrlist: seq[Attr]
@@ -300,9 +303,9 @@ type
     inputType* {.jsget: "type".}: InputType
     value* {.jsget.}: string
     internalChecked {.jsget: "checked".}: bool
+    files* {.jsget.}: seq[WebFile]
     xcoord*: int
     ycoord*: int
-    file*: WebFile
 
   HTMLAnchorElement* = ref object of HTMLElement
     relList {.jsget.}: DOMTokenList
@@ -447,6 +450,7 @@ jsDestructor(MimeTypeArray)
 jsDestructor(Screen)
 jsDestructor(History)
 jsDestructor(Storage)
+jsDestructor(Crypto)
 
 jsDestructor(Element)
 jsDestructor(HTMLElement)
@@ -2990,7 +2994,8 @@ func inputString*(input: HTMLInputElement): string =
     else:
       "SUBMIT"
   of itFile:
-    let s = if input.file != nil: input.file.name else: ""
+    #TODO multiple files?
+    let s = if input.files.len > 0: input.files[0].name else: ""
     s.padToWidth(int(input.attrulgz(satSize).get(20)))
   else: input.value
 
@@ -4483,7 +4488,7 @@ proc resetElement*(element: Element) =
     of itCheckbox, itRadio:
       input.setChecked(input.attrb(satChecked))
     of itFile:
-      input.file = nil
+      input.files.setLen(0)
     else:
       input.value = input.attr(satValue)
     input.setInvalid()
diff --git a/src/html/env.nim b/src/html/env.nim
index 54499b1a..efec53fe 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -167,6 +167,20 @@ func delete(this: var Storage; k: string): bool {.jsdelprop.} =
   this.removeItem(k)
   return true
 
+# Crypto
+proc getRandomValues(ctx: JSContext; crypto: var Crypto; array: JSValue):
+    JSValue {.jsfunc.} =
+  var view: JSArrayBufferView
+  if ctx.fromJS(array, view).isNone:
+    return JS_EXCEPTION
+  if view.t < 0 or view.t > cint(JS_TYPED_ARRAY_BIG_UINT64):
+    return JS_ThrowDOMException(ctx, "Wrong typed array type",
+      "TypeMismatchError")
+  if view.abuf.len > 65536:
+    return JS_ThrowDOMException(ctx, "Too large array", "QuotaExceededError")
+  crypto.urandom.recvDataLoop(view.abuf.p, int(view.abuf.len))
+  return JS_DupValue(ctx, array)
+
 proc addNavigatorModule*(ctx: JSContext) =
   ctx.registerType(Navigator)
   ctx.registerType(PluginArray)
@@ -174,6 +188,7 @@ proc addNavigatorModule*(ctx: JSContext) =
   ctx.registerType(Screen)
   ctx.registerType(History)
   ctx.registerType(Storage)
+  ctx.registerType(Crypto)
 
 proc fetch(window: Window; input: JSValue;
     init = RequestInit(window: JS_UNDEFINED)): JSResult[FetchPromise]
@@ -412,7 +427,7 @@ proc newWindow*(scripting: ScriptingMode; images, styling, autofocus: bool;
       origin: url.origin
     ),
     factory: factory,
-    urandom: urandom,
+    crypto: Crypto(urandom: urandom),
     imageTypes: imageTypes,
     userAgent: userAgent,
     referrer: referrer,
diff --git a/src/html/formdata.nim b/src/html/formdata.nim
index 909aa54d..1308213c 100644
--- a/src/html/formdata.nim
+++ b/src/html/formdata.nim
@@ -27,7 +27,7 @@ proc newFormData0*(entries: seq[FormDataEntry]; urandom: PosixStream):
 
 proc newFormData(ctx: JSContext; form: HTMLFormElement = nil;
     submitter: HTMLElement = nil): DOMResult[FormData] {.jsctor.} =
-  let urandom = ctx.getGlobal().urandom
+  let urandom = ctx.getGlobal().crypto.urandom
   let this = FormData(boundary: urandom.generateBoundary())
   if form != nil:
     if submitter != nil:
@@ -148,12 +148,12 @@ proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil;
           "on"
         entrylist.add((name, value))
       of itFile:
-        if field.file != nil:
+        for file in field.files:
           entrylist.add(FormDataEntry(
             name: name,
-            filename: field.file.name,
+            filename: file.name,
             isstr: false,
-            value: field.file
+            value: file
           ))
       of itHidden:
         if name.equalsIgnoreCase("_charset_"):
diff --git a/src/local/client.nim b/src/local/client.nim
index 87d15cc6..b1fcb2cc 100644
--- a/src/local/client.nim
+++ b/src/local/client.nim
@@ -169,7 +169,7 @@ proc newClient*(config: Config; forkserver: ForkServer; loaderPid: int;
     jsctx: jsctx,
     factory: newCAtomFactory(),
     loader: loader,
-    urandom: urandom,
+    crypto: Crypto(urandom: urandom),
     pager: newPager(config, forkserver, jsctx, warnings, urandom, loader),
     settings: EnvironmentSettings(scripting: smApp)
   )
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index a31ae744..b5fc6629 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -1300,7 +1300,8 @@ proc makeFormRequest(buffer: Buffer; parsedAction: URL; httpMethod: HttpMethod;
       RequestBody(t: rbtString, s: serializeFormURLEncoded(kvlist))
     of fetMultipart:
       #TODO with charset
-      let multipart = serializeMultipart(entryList, buffer.window.urandom)
+      let multipart = serializeMultipart(entryList,
+        buffer.window.crypto.urandom)
       RequestBody(t: rbtMultipart, multipart: multipart)
     of fetTextPlain:
       #TODO with charset
@@ -1379,7 +1380,7 @@ proc readSuccess*(buffer: Buffer; s: string; hasFd: bool): ReadSuccessResult
       let input = HTMLInputElement(buffer.document.focus)
       case input.inputType
       of itFile:
-        input.file = newWebFile(s, fd)
+        input.files = @[newWebFile(s, fd)]
         input.setInvalid()
         buffer.maybeReshape()
         res.repaint = true
@@ -1927,7 +1928,7 @@ proc cleanup(buffer: Buffer) =
   if gpstream != nil:
     gpstream.sclose()
     gpstream = nil
-  buffer.window.urandom.sclose()
+  buffer.window.crypto.urandom.sclose()
 
 proc launchBuffer*(config: BufferConfig; url: URL; attrs: WindowAttributes;
     ishtml: bool; charsetStack: seq[Charset]; loader: FileLoader;
diff --git a/src/version.nim b/src/version.nim
index 46c0060f..bdb59e7e 100644
--- a/src/version.nim
+++ b/src/version.nim
@@ -29,4 +29,4 @@ tryImport monoucha/version, "monoucha"
 static:
   checkVersion("chagashi", 0, 7, 0)
   checkVersion("chame", 1, 0, 3)
-  checkVersion("monoucha", 0, 9, 0)
+  checkVersion("monoucha", 0, 9, 1)