src: convert BE-utf16-string to LE before search
authorKarl Skomski <karl@skomski.com>
Fri, 9 Oct 2015 16:09:52 +0000 (18:09 +0200)
committerJames M Snell <jasnell@gmail.com>
Sat, 10 Oct 2015 17:20:18 +0000 (10:20 -0700)
On Big Endian platforms v8 strings are need to converted
to Little Endian before searching in utf16le buffer

Fixes: https://github.com/nodejs/node/issues/3283
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Michael Dawson <mhdawson@ca.ibm.com>
PR-URL: https://github.com/nodejs/node/pull/3295

src/node_buffer.cc

index 0492987..4df7a9f 100644 (file)
@@ -842,11 +842,27 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
       return args.GetReturnValue().Set(-1);
     }
 
-    result = SearchString(reinterpret_cast<const uint16_t*>(haystack),
-                          haystack_length / 2,
-                          reinterpret_cast<const uint16_t*>(*needle_value),
-                          needle_value.length(),
-                          offset / 2);
+    if (IsBigEndian()) {
+      StringBytes::InlineDecoder decoder;
+      decoder.Decode(Environment::GetCurrent(args), needle, args[3], UCS2);
+      const uint16_t* decoded_string =
+          reinterpret_cast<const uint16_t*>(decoder.out());
+
+      if (decoded_string == nullptr)
+        return args.GetReturnValue().Set(-1);
+
+      result = SearchString(reinterpret_cast<const uint16_t*>(haystack),
+                            haystack_length / 2,
+                            decoded_string,
+                            decoder.size() / 2,
+                            offset / 2);
+    } else {
+      result = SearchString(reinterpret_cast<const uint16_t*>(haystack),
+                            haystack_length / 2,
+                            reinterpret_cast<const uint16_t*>(*needle_value),
+                            needle_value.length(),
+                            offset / 2);
+    }
     result *= 2;
   } else if (enc == UTF8) {
     String::Utf8Value needle_value(needle);